(*  Title:      Length.thy
    Author:     Sven Linker

The length of cars visible to the owner of a given view.
*)

section\<open>Visible Length of Cars with Perfect Sensors\<close>
text\<open>
Given a sensor function, we can define the length
of a car \(c\) as perceived by the owner of a view \(v\). This
length is restricted by the size of the extension of the view \(v\),
but always given by a continuous interval, which may possibly
be degenerate (i.e., a point-interval).

The lemmas connect the end-points of the perceived length
with the end-points of the current view. Furthermore, they
show how the chopping and subview relations affect
the perceived length of a car.
\<close>

theory Length
  imports  Sensors
begin

context sensors
begin

definition len:: "view \<Rightarrow> traffic \<Rightarrow> cars \<Rightarrow> real_int"
  where len_def :"len v ( ts ) c ==
    if (left (space ts v c) > right (ext v))
      then  Abs_real_int (right (ext v),right (ext v))
    else
      if (right (space ts v c) < left (ext v))
        then Abs_real_int (left (ext v),left (ext v))
      else
        Abs_real_int (max (left (ext v)) (left (space ts v c)),
                      min (right (ext v)) (right (space ts v c)))"

lemma len_left: " left ((len v  ts) c) \<ge> left (ext v)"
    using Abs_real_int_inverse left_leq_right sensors.len_def sensors_axioms by auto

lemma len_right: " right ((len v  ts) c) \<le> right (ext v)"
  using Abs_real_int_inverse left_leq_right sensors.len_def sensors_axioms by auto

lemma len_sub_int:"len v ts c \<le> ext v"
  using less_eq_real_int_def len_left len_right by blast

lemma len_space_left:
  "left (space ts v c) \<le> right (ext v) \<longrightarrow> left (len v ts c) \<ge> left (space ts v c)"
proof
  assume assm:"left (space ts v c) \<le> right (ext v)"
  then show "left (len v ts c) \<ge> left (space ts v c)"
  proof (cases "right ((space ts v) c) < left (ext v)" )
    case True
    then show ?thesis using len_def len_left real_int.left_leq_right
      by (meson le_less_trans not_less order.asym)
  next
    case False
    then have "len v ts c =
    Abs_real_int ((max (left (ext v)) (left ((space ts v) c))),
                   min (right (ext v)) (right ((space ts v) c)))"
      using len_def assm by auto
    then have "left (len v ts c) = max (left (ext v)) (left ((space ts v) c))"
      using Abs_real_int_inverse False assm real_int.left_leq_right
      by auto
    then show ?thesis  by linarith
  qed
qed

lemma len_space_right:
  "right (space ts v c) \<ge> left (ext v) \<longrightarrow> right (len v ts c) \<le> right (space ts v c)"
proof
  assume assm:"right (space ts v c) \<ge> left (ext v)"
  then show "right (len v ts c) \<le> right (space ts v c)"
  proof (cases "left ((space ts v) c) > right (ext v)" )
    case True
    then show ?thesis using len_def len_right real_int.left_leq_right
      by (meson le_less_trans not_less order.asym)
  next
    case False
    then have "len v ts c =
      Abs_real_int (max (left (ext v)) (left ((space ts v) c)),
                     min (right (ext v)) (right ((space ts v) c)))"
      using len_def assm by auto
    then have "right (len v ts c) = min (right (ext v)) (right ((space ts v) c))"
      using Abs_real_int_inverse False assm real_int.left_leq_right
      by auto
    then show ?thesis  by linarith
  qed
qed

lemma len_hchop_left_right_border:
  "(len v ts c = ext v) \<and> (v=v1\<parallel>v2) \<longrightarrow> (right (len v1 ts c) = right (ext v1))"
proof
  assume assm:"((len v ts) c = ext v) \<and> (v=v1\<parallel>v2)"
  have l1:"left ((len v ts) c) = left (ext v)" using assm by auto
  from assm have l2:"left (ext v) = left (ext v1)"
    by (simp add: hchop_def real_int.rchop_def)
  from l1 and l2 have l3:"left ((len v ts) c) = left (ext v1)" by simp
  have r1:"right ((len v ts) c) = right (ext v)" using assm by auto
  have r2:"right (ext v1) \<le> right (ext v)"
    by (metis (no_types, lifting) assm hchop_def real_int.rchop_def
        real_int.left_leq_right )
  have r3:"right ((len v1 ts) c) \<le> right (ext v1)"
    using len_right by blast
  show "right ((len v1 ts) c) = right (ext v1)"
  proof (rule ccontr)
    assume contra:"right ((len v1 ts) c) \<noteq> right (ext v1)"
    with r3 have less:"right ((len v1 ts) c) < right (ext v1)" by simp
    show False
    proof (cases "left ((space ts v) c) \<le> right (ext v1)")
      assume neg1:"\<not> left ((space ts v) c) \<le> right (ext v1)"
      have "right ((len v1 ts) c) = right (ext v1)"
        using Abs_real_int_inverse left_space len_def neg1 right.rep_eq by auto
      with contra show False ..
    next
      assume less1:"left ((space ts v) c) \<le> right (ext v1)"
      show False
      proof (cases "right ((space ts v) c) \<ge> left (ext v1)")
        assume neg2:"\<not> left (ext v1) \<le> right ((space ts v) c)"
        have "right ((len v1 ts) c) = right (ext v1)"
        proof -
          have "(len v1 ts) c = Abs_real_int (left (ext v1),left (ext v1))"
            using len_def  neg2 assm hchop_def real_int.left_leq_right less1 space_def
            by auto
          hence  "right ((len v1 ts) c) = left ((len v1 ts )c)"
            using l3 assm contra less1 len_def neg2 r2 r3  real_int.left_leq_right
            by auto
          with l1 have r4:"right((len v1 ts)c ) = right (ext v)"
            using assm l2 len_def neg2 assm hchop_def less1 real_int.left_leq_right r2
              space_def
            by auto
          hence "right (ext v) = right (ext v1)"
            using r2 r3 by auto
          thus "right ((len v1 ts) c) = right (ext v1)"
            using r4 by auto
        qed
        with contra  show False ..
      next
        assume less2:"left (ext v1) \<le> right ((space ts v) c)"
        have len_in_type:
          "(max (left (ext v1)) (left ((space ts v) c)),
            min (right (ext v1)) (right ((space ts v) c)))
            \<in> {r :: real*real . fst r \<le> snd r}"
          using Rep_real_int less1 less2 by auto
        from less1 and less2 have len_def_v1:"len v1 (ts) c =
                Abs_real_int ((max (left (ext v1)) (left ((space ts v) c))),
                              min (right (ext v1)) (right ((space ts v) c)))"
          using len_def assm hchop_def  space_def  by auto
        with less have
          "min (right (ext v1)) (right ((space ts v) c)) = right ((space ts v) c)"
          using Abs_real_int_inverse len_in_type snd_conv by auto
        hence "right ((space ts v) c) \<le> right (ext v1)" by simp
        hence "right ((space ts v) c) \<le> right (ext v)"
          using r2 by linarith
        from len_def_v1 and less and len_in_type
        have "right ((space ts v) c) < right (ext v1)"
          using Abs_real_int_inverse sndI by auto
        hence r4:"right ((space ts v) c) < right (ext v)"
          using r2 by linarith
        from assm have len_v_in_type:
          "(max (left (ext v)) (left ((space ts v) c)),
            min (right (ext v)) (right ((space ts v) c)))
          \<in> {r :: real*real . fst r \<le> snd r}"
          using r4 l2 len_in_type by auto
        hence " right (len v ( ts) c) \<noteq> right (ext v)"
          using Abs_real_int_inverse Pair_inject r4 len_def real_int.left_leq_right
            surjective_pairing by auto
        with r1 show False by best
      qed
    qed
  qed
qed

lemma len_hchop_left_left_border:
  "((len v ts) c = ext v) \<and> (v=v1\<parallel>v2) \<longrightarrow> (left ((len v1 ts) c) = left (ext v1))"
proof
  assume assm:"((len v ts) c = ext v) \<and> (v=v1\<parallel>v2)"
  have l1:"left ((len v ts) c) = left (ext v)" using assm by auto
  from assm have l2:"left (ext v) = left (ext v1)"
    by (simp add: hchop_def real_int.rchop_def )
  from l1 and l2 have l3:"left ((len v ts) c) = left (ext v1)" by simp
  have r1:"right ((len v ts) c) = right (ext v)" using assm by auto
  have r2:"right (ext v1) \<le> right (ext v)"
    by (metis (no_types, lifting) assm hchop_def real_int.rchop_def
        real_int.left_leq_right )
  have r3:"right ((len v1 ts) c) \<le> right (ext v1)"
    using len_right by blast
  show "(left ((len v1 ts) c) = left (ext v1))"
  proof (cases
      "left ((space ts v) c) \<le> right (ext v1) \<and> right ((space ts v) c) \<ge> left (ext v1)")
    case True
    show "(left ((len v1 ts) c) = left (ext v1))"
    proof (rule ccontr)
      assume neq:" left (len v1 ( ts) c) \<noteq> left (ext v1)"
      then have greater: "left (len v1 ( ts) c) > left (ext v1)"
        by (meson dual_order.order_iff_strict len_left)
      have len_in_type:
        "(max (left (ext v1)) (left ((space ts v) c)),
           min (right (ext v1)) (right ((space ts v) c)))
            \<in> {r :: real*real . fst r \<le> snd r}"
        using Rep_real_int True by auto
      from True have "len v1 ( ts) c =
        Abs_real_int ((max (left (ext v1)) (left ((space ts v) c))),
                       min (right (ext v1)) (right ((space ts v) c)))"
        using len_def assm hchop_def space_def  by auto
      hence maximum:
        "left (len v1 ( ts) c) = max (left (ext v1)) (left ((space ts v) c))"
        using Abs_real_int_inverse len_in_type by auto
      have "max (left (ext v1)) (left ((space ts v) c)) = left ((space ts v) c)"
        using maximum neq by linarith
      hence "left ((space ts v) c) > left (ext v1)"
        using greater maximum by auto
      hence l4:"left ((space ts v) c) > left (ext v)" using l2 by auto
      with assm have len_v_in_type:
        "(max (left (ext v)) (left ((space ts v) c)),
          min (right (ext v)) (right ((space ts v) c)))
        \<in> {r :: real*real . fst r \<le> snd r}"
        using len_in_type r2 by auto
      hence " left (len v ( ts) c) \<noteq> left (ext v)"
        using Abs_real_int_inverse l4 sensors.len_def sensors_axioms by auto
      thus False using l1 by best
    qed
  next
    case False
    then have
      "\<not>left ((space ts v) c) \<le> right (ext v1) \<or> \<not>right ((space ts v) c) \<ge> left (ext v1)"
      by auto
    then show "(left ((len v1 ts) c) = left (ext v1))"
    proof
      assume negative:"\<not> left ((space ts v) c) \<le> right (ext v1)"
      then have "len v1 ( ts) c = Abs_real_int (right (ext v1),right (ext v1))"
        using len_def assm hchop_def space_def by auto
      hence empty:"left (len v1 ( ts) c) = right (len v1 ( ts) c)"
        by (metis real_int.chop_assoc2 real_int.chop_singleton_right real_int.rchop_def)
      have len_geq:"left(len v1 ( ts) c) \<ge> left (ext v)"
        using l2 len_left by auto
      show "left (len v1 ( ts) c) = left (ext v1)"
      proof (rule ccontr)
        assume contra:"left (len v1 ( ts) c) \<noteq> left (ext v1)"
        with len_left have "left (ext v1) < left (len v1 ( ts) c)  "
          using dual_order.order_iff_strict by blast
        hence l5:"left (ext v) < left (len v1 ( ts) c)" using l2 by auto
        hence l6:"left (len v ( ts) c) < left (len v1 ( ts) c)" using l1 by auto
        show "False"
        proof (cases "left ((space ts v) c) \<le> right (ext v)")
          case True
          have well_sp:"left ((space ts v) c) \<le> right ((space ts v) c)"
            using real_int.left_leq_right by auto
          have well_v:"left (ext v) \<le> right (ext v)"
            using real_int.left_leq_right by auto
          hence rs_geq_vl:"right ((space ts v) c) \<ge> left (ext v)"
            using empty len_geq negative r3 well_sp by linarith
          from True and rs_geq_vl have len_in_type:
            "(max (left (ext v)) (left ((space ts v) c)),
              min (right (ext v)) (right ((space ts v) c)))
              \<in> {r :: real*real . fst r \<le> snd r}"
            using CollectD CollectI Rep_real_int fst_conv snd_conv by auto
          have "len v (ts) c  =
                Abs_real_int (max (left (ext v)) (left ((space ts v) c)),
                               min (right (ext v)) (right ((space ts v) c)))"
            using len_def using True rs_geq_vl by auto
          hence max_less:
            "max (left (ext v)) (left ((space ts v) c)) <  left (len v1 ( ts) c)"
            using Abs_real_int_inverse
            by (metis (full_types) l5 assm fst_conv left.rep_eq len_in_type)
          show False
            using empty max_less negative r3 by auto
        next
          case False
          then have "len v ( ts) c = Abs_real_int (right (ext v), right (ext v))"
            using len_def by auto
          hence empty_len_v:"left (len v ( ts) c) = right (ext v)" using Abs_real_int_inverse
            by simp
          show False
            using l6 empty empty_len_v r2 r3 by linarith
        qed
      qed
    next
      have "space ts v1 c \<le> space ts v c" using assm hchop_def space_def  by auto
      hence r4:"right (space ts v1 c) \<le> right (space ts v c)"
        using  less_eq_real_int_def by auto
      assume left_outside:"\<not> left (ext v1) \<le> right ((space ts v) c)"
      hence "left (ext v1 ) > right (space ts v1 c)" using r4 by linarith
      then have "len v1 ( ts) c = Abs_real_int (left (ext v1),left (ext v1))"
        using len_def assm hchop_def real_int.left_leq_right r1 r2 l1 l2 l3 r3
        by (meson le_less_trans less_trans not_less)
      thus "(left ((len v1 ts) c) = left (ext v1))"
        using  Abs_real_int_inverse by auto
    qed
  qed
qed

lemma len_view_hchop_left:
  "((len v ts) c = ext v) \<and> (v=v1\<parallel>v2) \<longrightarrow> ((len v1 ts) c = ext v1)"
  by (metis Rep_real_int_inverse left.rep_eq len_hchop_left_left_border
      len_hchop_left_right_border prod.collapse right.rep_eq)

lemma len_hchop_right_left_border:
  "((len v ts) c = ext v) \<and> (v=v1\<parallel>v2) \<longrightarrow> (left ((len v2 ts) c) = left (ext v2))"
proof
  assume assm:"((len v ts) c = ext v) \<and> (v=v1\<parallel>v2)"
  have r1:"right ((len v ts) c) = right (ext v)" using assm by auto
  from assm have r2:"right (ext v) = right (ext v2)"
    by (simp add: hchop_def real_int.rchop_def )
  from r1 and r2 have r3:"right ((len v ts) c) = right (ext v2)" by simp
  have l1:"left ((len v ts) c) = left (ext v)" using assm by auto
  have l2:"left (ext v2) \<ge> left (ext v)"
    using assm less_eq_real_int_def real_int.chop_leq2 view.hchop_def by blast
  have l3:"left ((len v2 ts) c) \<ge> left (ext v2)"
    using len_left by blast
  show "left ((len v2 ts) c) = left (ext v2)"
  proof (rule ccontr)
    assume contra:"left ((len v2 ts) c) \<noteq> left (ext v2)"
    with l3 have less:"left ((len v2 ts) c) > left (ext v2)" by simp
    show False
    proof (cases "left ((space ts v) c) \<le> right (ext v2)")
      assume neg1:"\<not> left ((space ts v) c) \<le> right (ext v2)"
      have "left ((len v2 ts) c) = left (ext v2)"
      proof -
        have "(len v2 ts) c = Abs_real_int (right (ext v2),right (ext v2))"
          using len_def  neg1 assm hchop_def space_def  by auto
        thus "left ((len v2 ts) c) = left (ext v2)"
          using assm l2 l3 len_def neg1 r3 by auto
      qed
      with contra show False ..
    next
      assume less1:"left ((space ts v) c) \<le> right (ext v2)"
      show False
      proof (cases "right ((space ts v) c) \<ge> left (ext v2)")
        assume neg2:"\<not> left (ext v2) \<le> right ((space ts v) c)"
        have "space ts v2 c \<le> space ts v c" using assm hchop_def space_def  by auto
        hence "right (space ts v2 c) \<le> right (space ts v c)" using less_eq_real_int_def
          by auto
        with neg2 have greater:"left (ext v2 ) > right (space ts v2 c)" by auto
        have "left ((len v2 ts) c) = left (ext v2)"
        proof -
          have len_empty:"(len v2 ts) c = Abs_real_int (left (ext v2),left (ext v2))"
            using len_def  neg2 assm hchop_def   less1 space_def by auto
          have l4:"left((len v2 ts)c ) = left (ext v)"
            using Abs_real_int_inverse len_def less neg2  assm hchop_def
              CollectI len_empty prod.collapse prod.inject by auto
          hence "left (ext v) = left (ext v2)"
            using l2 l3 by auto
          thus "left ((len v2 ts) c) = left (ext v2)" using l4 by auto
        qed
        with contra  show False ..
      next
        assume less2:"left (ext v2) \<le> right ((space ts v) c)"
        have len_in_type:
          "(max (left (ext v2)) (left ((space ts v) c)),
            min (right (ext v2)) (right ((space ts v) c)))
            \<in> {r :: real*real . fst r \<le> snd r}"
          using Rep_real_int less1 less2 by auto
        from less1 and less2 have len_def_v2:"len v2 ( ts) c =
                Abs_real_int (max (left (ext v2)) (left ((space ts v) c)),
                              min (right (ext v2)) (right ((space ts v) c)))"
          using len_def assm hchop_def space_def  by auto
        with less have
          "max (left (ext v2)) (left ((space ts v) c)) = left ((space ts v) c)"
          using Abs_real_int_inverse len_in_type snd_conv by auto
        hence "left ((space ts v) c) \<ge> left (ext v2)" by simp
        hence "left ((space ts v) c) \<ge> left (ext v)"
          using l2 by auto
        from len_def_v2 and less and len_in_type
        have "left ((space ts v) c) > left (ext v2)"
          using Abs_real_int_inverse sndI by auto
        hence l5:"left ((space ts v) c) > left (ext v)"
          using l2 by linarith
        with assm have len_v_in_type:
          "(max (left (ext v)) (left (space ts v c)),
             min (right (ext v)) (right (space ts v c)))
          \<in> {r :: real*real . fst r \<le> snd r}"
          using r2 len_in_type by auto
        hence "left (len v ( ts) c) \<noteq> left (ext v)"
          using Abs_real_int_inverse Pair_inject l5 len_def real_int.left_leq_right
            surjective_pairing by auto
        with l1 show False by best
      qed
    qed
  qed
qed

lemma len_hchop_right_right_border:
  "((len v ts) c = ext v) \<and> (v=v1\<parallel>v2) \<longrightarrow> (right ((len v2 ts) c) = right (ext v2))"
proof
  assume assm:"((len v ts) c = ext v) \<and> (v=v1\<parallel>v2)"
  have r1:"right ((len v ts) c) = right (ext v)" using assm by auto
  from assm have r2:"right (ext v) = right (ext v2)"
    by (simp add: hchop_def real_int.rchop_def )
  from r1 and r2 have r3:"right ((len v ts) c) = right (ext v2)" by simp
  have l1:"left ((len v ts) c) = left (ext v)" using assm by auto
  have l2:"left (ext v2) \<le> right (ext v)"
    using assm view.h_chop_middle2 by blast
  have l3:"left ((len v2 ts) c) \<ge> left (ext v2)"
    using len_left by blast
  show "(right ((len v2 ts) c) = right (ext v2))"
  proof (cases
      "left ((space ts v) c) \<le> right (ext v2) \<and> right ((space ts v) c) \<ge> left (ext v2)")
    case True
    show "(right ((len v2 ts) c) = right (ext v2))"
    proof (rule ccontr)
      assume neq:" right (len v2 ( ts) c) \<noteq> right (ext v2)"
      then have lesser: "right (len v2 ( ts) c) < right (ext v2)"
        using len_right less_eq_real_def by blast
      have len_in_type:
        "(max (left (ext v2)) (left (space ts v c)),
          min (right (ext v2)) (right (space ts v c)))
            \<in> {r :: real*real . fst r \<le> snd r}"
        using Rep_real_int True by auto
      from True have
        "len v2 ( ts) c =
          Abs_real_int (max (left (ext v2)) (left (space ts v c)),
                         min (right (ext v2)) (right (space ts v c)))"
        using len_def assm hchop_def space_def by auto
      hence maximum:
        "right (len v2 ( ts) c) = min (right (ext v2)) (right ((space ts v) c))"
        using Abs_real_int_inverse len_in_type by auto
      have min_right:
        "min (right (ext v2)) (right ((space ts v) c)) = right ((space ts v) c)"
        using maximum neq by linarith
      hence "right ((space ts v) c) < right (ext v2)"
        using lesser maximum by auto
      hence right_v:"right ((space ts v) c) < right (ext v)"
          using r2 by auto
      have right_inside:"right ((space ts v) c) \<ge> left (ext v)"
        by (meson True assm less_eq_real_int_def less_eq_view_ext_def
            order_trans view.horizontal_chop_leq2)
      with assm and True and right_inside
      have len_v_in_type:
        "(max (left (ext v)) (left (space ts v c)),
          min (right (ext v)) (right (space ts v c)))
        \<in> {r :: real*real . fst r \<le> snd r}"
        using min_right r2 real_int.left_leq_right by auto
      hence " right (len v ( ts) c) \<noteq> right (ext v)"
        using Abs_real_int_inverse Pair_inject right_v len_def
          real_int.left_leq_right surjective_pairing
        by auto
      thus False using r1 by best
    qed
  next
    case False
    then have "\<not>left ((space ts v) c) \<le> right (ext v2) \<or>
               \<not>right ((space ts v) c) \<ge> left (ext v2)"
      by auto
    thus "right ((len v2 ts) c) = right (ext v2)"
    proof
      assume negative:"\<not> left ((space ts v) c) \<le> right (ext v2)"
      show ?thesis
       using left_space negative r1 r3 sensors.len_def sensors_axioms by auto
    next
      assume left_outside:"\<not> left (ext v2) \<le> right ((space ts v) c)"
      hence "left (ext v2) > right (space ts v2 c)"
        using assm hchop_def space_def by auto
      then have len:"len v2 ( ts) c = Abs_real_int (left (ext v2),left (ext v2))"
        by (metis (no_types, hide_lams) len_def l2 le_less_trans not_less order.asym
            space_nonempty r2)
      show "(right ((len v2 ts) c) = right (ext v2))"
      proof (cases "right ((space ts v) c) \<ge> left (ext v)")
        assume "\<not> left (ext v) \<le> right ((space ts v) c)"
        hence len_empty:"len v (ts) c = Abs_real_int (left (ext v), left (ext v))"
          using len_def real_int.left_leq_right Abs_real_int_inverse
          by (meson less_trans not_less space_nonempty)
        show "(right ((len v2 ts) c) = right (ext v2))"
          by (metis (no_types, hide_lams) Rep_real_int_inverse assm dual_order.antisym
              left.rep_eq len len_empty prod.collapse real_int.chop_singleton_left
              real_int.rchop_def right.rep_eq view.h_chop_middle1 view.hchop_def)
      next
        assume "left (ext v) \<le> right ((space ts v) c)"
        then show ?thesis
          using l2 left_outside len_space_right r1  by fastforce
      qed
    qed
  qed
qed

lemma len_view_hchop_right:
  "((len v ts) c = ext v) \<and> (v=v1\<parallel>v2) \<longrightarrow> ((len v2 ts) c = ext v2)"
  by (metis Rep_real_int_inverse left.rep_eq len_hchop_right_left_border
      len_hchop_right_right_border prod.collapse right.rep_eq)

lemma len_compose_hchop:
  "(v=v1\<parallel>v2) \<and> (len v1 ( ts) c = ext v1) \<and> (len v2 ( ts) c = ext v2)
     \<longrightarrow> (len v ( ts) c = ext v)"
proof
  assume assm:"(v=v1\<parallel>v2) \<and> (len v1 ( ts) c = ext v1) \<and> (len v2 ( ts) c = ext v2)"
  then have left_v1:"left (len v1 ( ts) c) = left (ext v1)" by auto
  from assm have right_v1:"right (len v1 ( ts) c) = left (ext v2)"
    by (simp add: hchop_def real_int.rchop_def )
  from assm have left_v2:"left (len v2 ( ts) c) = right (ext v1)"
    using right_v1 by auto
  from assm have right_v2:"right (len v2 ( ts) c) = right (ext v2)" by auto
  show "(len v ( ts) c = ext v)"
  proof (cases " left ((space ts v) c) > right (ext v)")
    case True
    then have "left (space ts v c) > right (ext v2)" using assm right_v2
      by (simp add: hchop_def real_int.rchop_def )
    then have "left (space ts v2 c) > right( ext v2)"
      using assm hchop_def sensors.space_def sensors_axioms  by auto
    then have "len v2 ts c = Abs_real_int(right (ext v2), right (ext v2))"
      using len_def by simp
    then have "ext v2 = Abs_real_int(right (ext v2), right (ext v2))" using assm by simp
    then have "\<parallel>ext v2\<parallel> = 0"
      by (metis Rep_real_int_inverse fst_conv left.rep_eq
          real_int.chop_singleton_right real_int.length_zero_iff_borders_eq
          real_int.rchop_def right.rep_eq snd_conv surj_pair)
    then have "ext v = ext v1"
      using assm hchop_def real_int.rchop_def real_int.chop_empty2
      by simp
    then show ?thesis
      using assm hchop_def len_def sensors.space_def sensors_axioms
      by auto
  next
    case False
    then have in_left:"left (space ts v c) \<le> right (ext v)" by simp
    show "len v ts c = ext v"
    proof (cases "right (space ts v c) < left (ext v)")
      case True
      then have "right (space ts v c) < left (ext v1)" using assm left_v1
        by (simp add: hchop_def real_int.rchop_def)
      then have out_v1:"right (space ts v1 c) < left (ext v1)"
        using assm hchop_def sensors.space_def sensors_axioms  by auto
      then have "len v1 ts c = Abs_real_int(left (ext v1), left (ext v1))"
        using len_def in_left
        by (meson le_less_trans less_trans not_le real_int.left_leq_right)
      then have "ext v1 = Abs_real_int (left (ext v1), left (ext v1))" using assm by simp
      then have "\<parallel>ext v1\<parallel> = 0"
        by (metis add.right_neutral real_int.chop_singleton_left
            real_int.length_zero_iff_borders_eq real_int.rchop_def real_int.shift_def
            real_int.shift_zero)
      then have "ext v = ext v2" using assm hchop_def real_int.rchop_def real_int.chop_empty1
        by auto
      then show ?thesis
        using assm hchop_def len_def sensors.space_def sensors_axioms by auto
    next
      case False
      then  have in_right:"right (space ts v c) \<ge> left (ext v)"  by simp
      have f1: "own v = own v2" using assm hchop_def
        by (auto)
      have f2: "own v = own v1"
        using assm hchop_def  by auto
      have chop:"R_Chop(ext v,ext v1,ext v2)" using assm hchop_def
        by (auto )
      have len:"len v ts c = Abs_real_int(max (left (ext v)) (left (space ts v c)),
                      min (right (ext v)) (right (space ts v c)))"
        using len_def in_left in_right by simp
      have len1:"len v1 ts c = Abs_real_int(max (left (ext v1)) (left (space ts v1 c)),
                      min (right (ext v1)) (right (space ts v1 c)))"
        by (metis assm f2 f1 chop assm in_left in_right len_def len_space_left
            not_le real_int.rchop_def space_def)
      then have "max (left (ext v1)) (left (space ts v1 c)) = left (len v1 ts c)"
        by (metis assm chop f1 f2 in_left len_space_left max.orderE
            real_int.rchop_def space_def)
      then have left_border:"max (left (ext v1)) (left (space ts v1 c)) = left (ext v1)"
        using left_v1 by simp
      have len2:"len v2 ts c = Abs_real_int(max (left (ext v2)) (left (space ts v2 c)),
                      min (right (ext v2)) (right (space ts v2 c)))"
        by (metis len_def in_left in_right assm f2 f1 chop len_space_right not_le
            real_int.rchop_def space_def)
      then have "min (right (ext v2)) (right (space ts v2 c)) = right (len v2 ts c)"
        by (metis assm chop f1 f2 in_right len_space_right min.absorb_iff1
            real_int.rchop_def space_def)
      then have right_border:
        "min (right (ext v2)) (right (space ts v2 c)) = right (ext v2)"
        using right_v2 by simp
      have "left (space ts v c) = left (space ts v1 c)"
        using assm hchop_def sensors.space_def sensors_axioms by auto
      then have max:
        "  max (left (ext v)) (left (space ts v c))
         = max (left (ext v1)) (left (space ts v1 c))"
        using assm hchop_def real_int.rchop_def  by auto
      have "right (space ts v c) = right (space ts v2 c)"
        using assm hchop_def sensors.space_def sensors_axioms by auto
      then have min:
        "  min (right (ext v)) (right (space ts v c))
         = min (right (ext v2)) (right (space ts v2 c))"
        using assm hchop_def real_int.rchop_def by auto
      show ?thesis
        by (metis min max left_border right_border False add.right_neutral
            chop in_left len_def not_le real_int.rchop_def real_int.shift_def
            real_int.shift_zero)
    qed
  qed
qed

lemma len_stable:"(v=v1--v2) \<longrightarrow> len v1 ts c = len v2 ts c"
proof
  assume assm:"v=v1--v2"
  then have ext_eq1:"ext v = ext v1" and ext_eq2:"ext v = ext v2"
    using vchop_def by auto
  hence ext1_eq_ext2:"ext v1 = ext v2" by simp
  show "len v1 ts c = len v2 ts c"
    using assm ext1_eq_ext2 left_space right_space sensors.len_def sensors_axioms
      view.vertical_chop_own_trans by auto
qed

lemma len_empty_on_subview1:
  "\<parallel>len v ( ts) c\<parallel> = 0 \<and> (v=v1\<parallel>v2) \<longrightarrow> \<parallel>len v1 ( ts) c\<parallel> = 0"
proof
  assume assm:"\<parallel>len v ( ts) c\<parallel> = 0 \<and> (v=v1\<parallel>v2)"
  then have len_v_borders:"left (len v ( ts) c) = right (len v ( ts) c)"
    by (simp add:real_int.length_zero_iff_borders_eq)
  show "\<parallel>len v1 ( ts) c\<parallel> = 0"
  proof (cases "left ((space ts v) c) > right (ext v1)")
    assume left_outside_v1:"left ((space ts v) c) > right (ext v1)"
    thus "\<parallel>len v1 ( ts) c\<parallel> = 0"
      using Abs_real_int_inverse assm fst_conv hchop_def len_def real_int.length_zero_iff_borders_eq
        mem_Collect_eq snd_conv space_def  by auto
  next
    assume left_inside_v1:"\<not>left ((space ts v) c) > right (ext v1)"
    show "\<parallel>len v1 ( ts) c\<parallel> = 0"
    proof (cases "left (ext v1) > right ((space ts v) c)")
      assume right_outside_v1:"left (ext v1) > right ((space ts v) c)"
      hence "left (ext v1) > right ((space ts v1) c)" using assm hchop_def space_def
        by auto
      thus "\<parallel>len v1 (ts) c\<parallel> = 0"
        using assm hchop_def len_def real_int.length_def  Abs_real_int_inverse by auto
    next
      assume right_inside_v1:"\<not>left (ext v1) > right ((space ts v) c)"
      have len_v1:
        "len v1 ( ts) c = Abs_real_int (max (left (ext v1)) (left (space ts v c)),
                                        min (right (ext v1)) (right (space ts v c)))"
        using left_inside_v1 len_def right_inside_v1 assm hchop_def space_def by auto
      from left_inside_v1 and right_inside_v1 have inside_v:
        "\<not>left (space ts v c) > right (ext v) \<and> \<not>left (ext v) > right (space ts v c)"
      proof -
        have "fst (Rep_real_int (ext v2)) \<le> snd (Rep_real_int (ext v))"
          using assm view.h_chop_middle2 by force
        then show ?thesis
          using assm left_inside_v1 real_int.rchop_def right_inside_v1 view.hchop_def
          by force
      qed
      hence len_v:
        "len v ts c = Abs_real_int (max (left (ext v)) (left (space ts v c)),
                                    min (right (ext v)) (right (space ts v c)))"
        by (simp add: len_def)
      have less_eq:
        "  max (left (ext v)) (left (space ts v c))
         \<le> min (right (ext v)) (right (space ts v c))"
        using inside_v real_int.left_leq_right by auto
      from len_v have len_v_empty:
        "  max (left (ext v)) (left ((space ts v) c))
         = min (right (ext v)) (right ((space ts v) c))"
        using Abs_real_int_inverse Rep_real_int_inverse inside_v
        len_v_borders local.less_eq by auto
      have left_len_eq:
        " max (left (ext v)) (left (space ts v c))
        = max (left (ext v1)) (left (space ts v c))"
        using assm hchop_def real_int.rchop_def  by auto
      have right_len_leq:
        "  min (right (ext v)) (right (space ts v c))
         \<ge> min (right (ext v1)) (right (space ts v c))"
        by (metis (no_types, hide_lams) assm min.bounded_iff min_less_iff_conj not_le
            order_refl real_int.rchop_def view.h_chop_middle2 view.hchop_def)
      hence left_geq_right:
        "  max (left (ext v1)) (left (space ts v c))
         \<ge> min (right (ext v1)) (right (space ts v c))"
        using left_len_eq len_v_empty by auto
      thus "\<parallel>len v1 ( ts) c\<parallel> = 0"
      proof -
        have f1:
          " \<not> max (left (ext v)) (left (space ts v c))
            \<le> min (right (ext v1)) (right (space ts v c))
          \<or>
              min (right (ext v1)) (right (space ts v c))
            = max (left (ext v)) (left (space ts v c))"
          by (metis antisym_conv left_geq_right left_len_eq)
        have
          "\<And>r. \<not> left (ext v1) \<le> r
             \<or> \<not> left (space ts v c) \<le> r
             \<or> max (left (ext v)) (left (space ts v c)) \<le> r"
          using left_len_eq by auto
        then have
          "  min (right (ext v1)) (right (space ts v c))
           = max (left (ext v)) (left (space ts v c))"
          using f1 inside_v left_inside_v1 real_int.left_leq_right by force
        then show ?thesis
          using assm left_len_eq len_v len_v1 len_v_empty by auto
      qed
    qed
  qed
qed

lemma len_empty_on_subview2:
  "\<parallel>len v ts c\<parallel> = 0 \<and> (v=v1\<parallel>v2) \<longrightarrow> \<parallel>len v2 ts c\<parallel> = 0"
proof
  assume assm:"\<parallel>len v ( ts) c\<parallel> = 0 \<and> (v=v1\<parallel>v2)"
  then have len_v_borders:"left (len v ( ts) c) = right (len v ( ts) c)"
     by (simp add:real_int.length_zero_iff_borders_eq)
  show "\<parallel>len v2 ( ts) c\<parallel> = 0"
  proof (cases "left ((space ts v) c) > right (ext v2)")
    assume left_outside_v2:"left ((space ts v) c) > right (ext v2)"
    thus "\<parallel>len v2 ( ts) c\<parallel> = 0"
      using Abs_real_int_inverse assm fst_conv hchop_def len_def
        real_int.length_zero_iff_borders_eq mem_Collect_eq snd_conv space_def
      by auto
  next
    assume left_inside_v2:"\<not>left (space ts v c) > right (ext v2)"
    show "\<parallel>len v2 ( ts) c\<parallel> = 0"
    proof (cases "left (ext v2) > right (space ts v c)")
      assume right_outside_v2:"left (ext v2) > right ((space ts v) c)"
      thus "\<parallel>len v2 ( ts) c\<parallel> = 0"
        using Abs_real_int_inverse assm fst_conv hchop_def len_def
          real_int.length_zero_iff_borders_eq mem_Collect_eq snd_conv
          right_outside_v2 space_def
        by auto
    next
      assume right_inside_v2:"\<not>left (ext v2) > right ((space ts v) c)"
      have len_v2:
        "len v2 ts c = Abs_real_int (max (left (ext v2)) (left (space ts v c)),
                                     min (right (ext v2)) (right (space ts v c)))"
        using left_inside_v2 len_def right_inside_v2 assm hchop_def space_def by auto
      from left_inside_v2 and right_inside_v2 have inside_v:
        "\<not>left ((space ts v) c) > right (ext v) \<and> \<not>left (ext v) > right ((space ts v) c)"
      proof -
        have "left (ext v) \<le> right (ext v1)"
          using assm view.h_chop_middle1 by auto
        then show ?thesis
          using assm left_inside_v2 real_int.rchop_def right_inside_v2 view.hchop_def
          by force
      qed
      hence len_v:
        "len v ts c = Abs_real_int (max (left (ext v)) (left (space ts v c)),
                                    min (right (ext v)) (right (space ts v c)))"
        by (simp add: len_def)
      have less_eq:
        "  max (left (ext v)) (left (space ts v c))
         \<le> min (right (ext v)) (right (space ts v c))"
        using inside_v real_int.left_leq_right by auto
      from len_v have len_v_empty:
        "  max (left (ext v)) (left (space ts v c))
         = min (right (ext v)) (right (space ts v c))"
        using Abs_real_int_inverse Rep_real_int_inverse inside_v
        using len_v_borders local.less_eq by auto
      have left_len_eq:
        "  max (left (ext v)) (left (space ts v c))
        \<le> max (left (ext v2)) (left (space ts v c))"
        by (metis (no_types, hide_lams) assm left_leq_right max.mono order_refl
            real_int.rchop_def view.hchop_def)
      have right_len_leq:
        "  min (right (ext v)) (right (space ts v c))
         = min (right (ext v2)) (right (space ts v c))"
        using assm real_int.rchop_def view.hchop_def by auto
      hence left_geq_right:
        " max (left (ext v2)) (left (space ts v c))
        \<ge> min (right (ext v2)) (right (space ts v c))"
        using left_len_eq len_v_empty by auto
      then have
        "  max (left (ext v2)) (left (space ts v2 c))
         \<ge> min (right (ext v2)) (right (space ts v2 c))"
        using assm hchop_def space_def  by auto
      then have
        "  max (left (ext v2)) (left (space ts v2 c))
         = min (right (ext v2)) (right (space ts v2 c))"
        by (metis (no_types, hide_lams) antisym_conv assm hchop_def len_v_empty
            max_def min.bounded_iff not_le space_def right_inside_v2 right_len_leq
            view.h_chop_middle2)
      thus "\<parallel>len v2 ( ts) c\<parallel> = 0"
        by (metis (no_types, hide_lams)  assm hchop_def len_v len_v2 len_v_empty
            space_def right_len_leq)
    qed
  qed
qed

lemma len_hchop_add:
  "(v=v1\<parallel>v2) \<longrightarrow> \<parallel>len v ts c\<parallel> = \<parallel>len v1 ts c\<parallel> + \<parallel>len v2 ts c\<parallel>"
proof
  assume chop:"v=v1\<parallel>v2"
  show "\<parallel>len v ts c\<parallel> = \<parallel>len v1 ts c\<parallel> + \<parallel>len v2 ts c\<parallel>"
  proof (cases "left ((space ts v) c) > right (ext v)")
    assume outside_right:"left (space ts v c) > right (ext v)"
    hence len_zero:"\<parallel>len v ( ts) c\<parallel> = 0"
      by (simp add: Abs_real_int_inverse  len_def real_int.length_zero_iff_borders_eq
          snd_eqD)
    with chop have "\<parallel>len v1 ts c\<parallel> + \<parallel>len v2 ts c\<parallel> = 0"
      by (metis add_cancel_right_left len_empty_on_subview1 len_empty_on_subview2)
    thus ?thesis using len_zero by (simp)
  next
    assume inside_right:"\<not>left ((space ts v) c) > right (ext v)"
    show "\<parallel>len v ts c\<parallel> = \<parallel>len v1 ts c\<parallel> + \<parallel>len v2 ts c\<parallel>"
    proof (cases " left (ext v) > right ((space ts v) c) ")
      assume outside_left:" left (ext v) > right (space ts v c) "
      hence len_zero:"\<parallel>len v ( ts) c\<parallel> = 0"
        by (simp add: Abs_real_int_inverse len_def real_int.length_zero_iff_borders_eq
            snd_eqD)
      with chop have "\<parallel>len v1 ts c\<parallel> + \<parallel>len v2 ts c\<parallel> = 0"
        by (metis add_cancel_right_left len_empty_on_subview1 len_empty_on_subview2)
      thus ?thesis using len_zero by (simp )
    next
      assume inside_left:" \<not>left (ext v) > right ((space ts v) c) "
      hence len_def_v:"len v ( ts) c =
                Abs_real_int ((max (left (ext v)) (left ((space ts v) c))),
                              min (right (ext v)) (right ((space ts v) c)))"
        using len_def inside_left inside_right by simp
      from inside_left and inside_right have
        len_in_type:"(max (left (ext v)) (left ((space ts v) c)),
                      min (right (ext v)) (right ((space ts v) c)))
                     \<in> {r :: real*real . fst r \<le> snd r}"
        using CollectD CollectI Rep_real_int fst_conv snd_conv by auto
      show "\<parallel>len v ( ts) c\<parallel> = \<parallel>len v1 ( ts) c\<parallel> + \<parallel>len v2 ( ts) c\<parallel>"
      proof (cases "right (len v ( ts) c) < right (ext v1)")
        assume inside_v1:"right (len v ( ts) c) < right (ext v1)"
        then have min_less_v1:
          "min (right (ext v)) (right (space ts v c)) < right (ext v1)"
          using Abs_real_int_inverse len_in_type len_def_v by auto
        hence outside_v2:"right ((space ts v) c) < left (ext v2)"
        proof -
          have "left (ext v2) = right (ext v1)"
            using chop real_int.rchop_def view.hchop_def by force
          then show ?thesis
            by (metis (no_types) chop dual_order.order_iff_strict
                min_less_iff_conj min_less_v1 not_less view.h_chop_middle2)
        qed
        hence len_v2_0:"\<parallel>len v2 ( ts) c\<parallel> = 0" using  Abs_real_int_inverse len_def
            real_int.length_zero_iff_borders_eq outside_v2  snd_eqD Rep_real_int_inverse
            chop hchop_def prod.collapse real_int.rchop_def real_int.chop_singleton_right
            space_def
            by auto
        have inside_left_v1:"  \<not>left (ext v1) > right ((space ts v) c) "
          using chop hchop_def inside_left real_int.rchop_def  by auto
        have inside_right_v1:"\<not>left ((space ts v) c) > right (ext v1)"
          by (meson inside_right less_trans min_less_iff_disj min_less_v1
              order.asym space_nonempty)
        have len1_def:"len v1 ( ts) c =
                Abs_real_int ((max (left (ext v1)) (left ((space ts v) c))),
                              min (right (ext v1)) (right ((space ts v) c)))"
          using len_def inside_left_v1 inside_right_v1 chop hchop_def space_def
          by auto
        hence "\<parallel>len v ts c\<parallel> = \<parallel>len v1 ts c\<parallel>"
        proof -
          have "right (ext v1) \<le> right (ext v2)"
            using chop left_leq_right real_int.rchop_def view.hchop_def by auto
          then show ?thesis
            using chop len1_def len_def_v min_less_v1 real_int.rchop_def view.hchop_def
            by auto
        qed
        thus "\<parallel>len v ts c\<parallel> = \<parallel>len v1 ts c\<parallel> + \<parallel>len v2 ts c\<parallel>"
          using len_v2_0 by (simp)
      next
        assume r_inside_v2:"\<not> right (len v ( ts) c) < right (ext v1)"
        show "\<parallel>len v ( ts) c\<parallel> = \<parallel>len v1 ( ts) c\<parallel> + \<parallel>len v2 ( ts) c\<parallel>"
        proof (cases "left (len v ( ts) c) > left (ext v2)")
          assume inside_v2:"left (len v ( ts) c) > left (ext v2)"
          hence max_geq_v1:"max (left (ext v)) (left ((space ts v) c)) > left (ext v2)"
            using Abs_real_int_inverse len_in_type len_def by (simp )
          hence outside_v1:"left ((space ts v) c) > right (ext v1)"
          proof -
            have "left (ext v) \<le> right (ext v1)"
              by (meson chop view.h_chop_middle1)
            then show ?thesis
              using chop max_geq_v1 real_int.rchop_def view.hchop_def by fastforce
          qed
          hence len_v1_0:"\<parallel>len v1 ts c\<parallel> = 0"
            using Abs_real_int_inverse len_def real_int.length_zero_iff_borders_eq
              outside_v1 snd_eqD Rep_real_int_inverse chop hchop_def prod.collapse
              real_int.rchop_def real_int.chop_singleton_right space_def
            by auto
          have inside_left_v2:"  \<not>left (ext v2) > right ((space ts v) c) "
            by (meson inside_left less_max_iff_disj less_trans max_geq_v1 order.asym
                space_nonempty)
          have inside_right_v2:"\<not>left ((space ts v) c) > right (ext v2)"
            using chop hchop_def inside_right real_int.rchop_def  by auto
          have len2_def:"len v2 ( ts) c =
                Abs_real_int ((max (left (ext v2)) (left ((space ts v) c))),
                              min (right (ext v2)) (right ((space ts v) c)))"
            using len_def inside_left_v2 inside_right_v2 hchop_def chop space_def
            by auto
          hence "\<parallel>len v ts c\<parallel> = \<parallel>len v2 ts c\<parallel>"
          proof -
            have "left (ext v) \<le> left (ext v2)"
              by (metis (no_types) chop real_int.rchop_def view.h_chop_middle1
                  view.hchop_def)
            then show ?thesis
              using chop inside_left inside_right len2_def len_def outside_v1
                real_int.rchop_def view.hchop_def
              by auto
          qed
          thus "\<parallel>len v ts c\<parallel> = \<parallel>len v1 ts c\<parallel> + \<parallel>len v2 ts c\<parallel>"
            using len_v1_0 by (simp)
        next
          assume l_inside_v1: "\<not>left (len v ( ts) c) > left (ext v2)"
          have inside_left_v1:"  \<not>left (ext v1) > right ((space ts v) c) "
            using chop hchop_def inside_left real_int.rchop_def  by auto
          have inside_right_v1:"\<not>left ((space ts v) c) > right (ext v1)"
            using Abs_real_int_inverse chop hchop_def l_inside_v1 len_in_type
              len_def real_int.rchop_def
            by auto
          hence len1_def:"len v1 ( ts) c =
                Abs_real_int ((max (left (ext v1)) (left ((space ts v) c))),
                              min (right (ext v1)) (right ((space ts v) c)))"
            using inside_left_v1 inside_right_v1 len_def chop hchop_def space_def
            by (simp )
          from inside_left_v1 and inside_right_v1 have len1_in_type:
            "(max (left (ext v1)) (left (space ts v c)),
              min (right (ext v1)) (right (space ts v c)))
            \<in> {r :: real*real . fst r \<le> snd r}"
            using CollectD CollectI Rep_real_int fst_conv snd_conv by auto
          have inside_left_v2:"  \<not>left (ext v2) > right ((space ts v) c) "
            using real_int.rchop_def hchop_def inside_left chop Abs_real_int_inverse
              len_def_v len_in_type r_inside_v2 snd_conv
            by auto
          have inside_right_v2:"\<not>left ((space ts v) c) > right (ext v2)"
            using Abs_real_int_inverse chop hchop_def l_inside_v1 len_in_type len_def
              real_int.rchop_def
            by auto
          hence len2_def:"len v2 ts c =
                Abs_real_int (max (left (ext v2)) (left (space ts v c)),
                              min (right (ext v2)) (right (space ts v c)))"
            using inside_left_v2 inside_right_v2 len_def chop hchop_def space_def
            by (auto )
          from inside_left_v2 and inside_right_v2 have len2_in_type:
            "(max (left (ext v2)) (left (space ts v c)),
              min (right (ext v2)) (right (space ts v c)))
            \<in> {r :: real*real . fst r \<le> snd r}"
            using CollectD CollectI Rep_real_int fst_conv snd_conv
            by auto
          have left_v_v1:"left (ext v) = left (ext v1)"
            using chop hchop_def real_int.rchop_def  by auto
          have max:
               "max (left (ext v)) (left (space ts v c)) =
                max (left (ext v1)) (left (space ts v c))"
            using left_v_v1 by auto
          have right_v_v2:"right (ext v) = right (ext v2)"
            using chop hchop_def real_int.rchop_def  by auto
          have min: "(min (right (ext v)) (right ((space ts v) c))) =
                (min (right (ext v2)) (right ((space ts v) c)))"
            using right_v_v2 by auto
          from max have left_len_v1_v:"left (len v ( ts) c) = left (len v1 ( ts) c)"
            using Abs_real_int_inverse fst_conv len1_def len1_in_type
              len_def_v len_in_type
            by auto
          from min have right_len_v2_v:"right (len v ( ts) c) = right (len v2 ( ts) c)"
            using Abs_real_int_inverse fst_conv len1_def len2_in_type len_def_v
              len_in_type using len2_def snd_eqD by auto
          have "right (len v1 ( ts) c) = left (len v2 ( ts) c)"
            using Abs_real_int_inverse chop hchop_def len1_def len1_in_type len2_def
              len2_in_type real_int.rchop_def
            by auto
          thus "\<parallel>len v ts c\<parallel> = \<parallel>len v1 ts c\<parallel> + \<parallel>len v2 ts c\<parallel>"
            using left_len_v1_v real_int.consec_add right_len_v2_v  by simp
        qed
      qed
    qed
  qed
qed

lemma len_non_empty_inside:
 "\<parallel>len v ( ts) c\<parallel> > 0
  \<longrightarrow> left (space ts v c) < right (ext v) \<and> right (space ts v c) > left (ext v)"
proof
  assume assm: "\<parallel>len v ( ts) c\<parallel> > 0"
  show "left ((space ts v) c) < right (ext v) \<and> right ((space ts v) c) > left (ext v)"
  proof (rule ccontr)
    assume "\<not>(left ((space ts v) c) < right (ext v)
              \<and> right ((space ts v) c) > left (ext v))"
    hence "\<not>left ((space ts v) c) < right (ext v)
          \<or> \<not>right ((space ts v) c) > left (ext v)"
      by best
    thus False
    proof
      assume "\<not>left ((space ts v) c) < right (ext v)"
      hence "(left ((space ts v) c) = right (ext v))
            \<or> left ((space ts v) c) > right (ext v)"
        by auto
      thus False
      proof
        assume left_eq:"left ((space ts v) c) = right (ext v)"
        hence inside_left:"right ((space ts v) c) \<ge> left (ext v)"
          by (metis order_trans real_int.left_leq_right)
        from left_eq and inside_left have len_v:
          "len v ( ts) c = Abs_real_int (max (left (ext v)) (left (space ts v c)),
                                         min (right (ext v)) (right (space ts v c)))"
          using len_def by auto
        hence "len v ( ts) c = Abs_real_int (left (space ts v c), left(space ts v c))"
          by (metis left_eq max_def min_def real_int.left_leq_right)
        thus False using Abs_real_int_inverse assm real_int.length_def by auto
      next
        assume "left ((space ts v) c) > right (ext v)"
        thus False
          using Abs_real_int_inverse assm len_def real_int.length_def by auto
      qed
    next
      assume "\<not>right ((space ts v) c) > left (ext v)"
      hence " right ((space ts v) c) = left (ext v)
            \<or> right ((space ts v) c) < left (ext v)"
        by auto
      thus False
      proof
        assume right_eq:"right ((space ts v) c) = left (ext v)"
        hence inside_right:"right (ext v) \<ge> left ((space ts v) c)"
          by (metis order_trans real_int.left_leq_right)
        from right_eq and inside_right have len_v:
          "len v ts c = Abs_real_int (max (left (ext v)) (left (space ts v c)),
                              min (right (ext v)) (right (space ts v c)))"
          using len_def by auto
        hence
          "len v ( ts) c = Abs_real_int(right (space ts v c), right (space ts v c))"
          by (metis max.commute max_def min_def real_int.left_leq_right right_eq)
        thus False using Abs_real_int_inverse assm real_int.length_def by auto
      next
        assume right_le:"right ((space ts v) c) < left (ext v)"
        thus False
          by (metis (no_types, hide_lams) Rep_real_int_inverse assm left.rep_eq len_def
              length_zero_iff_borders_eq less_irrefl prod.collapse real_int.rchop_def
              right.rep_eq view.hchop_def view.horizontal_chop_empty_left
              view.horizontal_chop_empty_right)
      qed
    qed
  qed
qed

lemma len_fills_subview:
  "\<parallel>len v ts c\<parallel> > 0
      \<longrightarrow> (\<exists> v1 v2 v3 v'. (v=v1\<parallel>v2) \<and> (v2=v'\<parallel>v3) \<and> len v' ts c = ext v' \<and>
                          \<parallel>len v' ts c\<parallel> = \<parallel>len v ts c\<parallel>)"
proof
  assume assm: "\<parallel>len v ( ts) c\<parallel> > 0"
  show " \<exists> v1 v2 v3 v'. (v=v1\<parallel>v2) \<and> (v2=v'\<parallel>v3) \<and> len v' ( ts) c = ext v' \<and>
          \<parallel>len v' ( ts) c\<parallel> = \<parallel>len v ( ts) c\<parallel>"
  proof -
    from assm have inside:
      "left ((space ts v) c) < right (ext v) \<and> right ((space ts v) c) > left (ext v)"
      using len_non_empty_inside by auto
    hence len_v:
      "len v ( ts) c = Abs_real_int (max (left (ext v)) (left (space ts v c)),
                              min (right (ext v)) (right (space ts v c)))"
      using len_def by auto
    obtain v1 and v2 and v3 and v'
      where v1:
        "v1=\<lparr>ext =Abs_real_int(left(ext v), left (len v ts c)),
             lan = lan v,
             own = own v\<rparr>"
      and v2:
      "v2=\<lparr>ext =Abs_real_int(left(len v ts c), right (ext v)),
           lan = lan v,
           own = own v\<rparr>"
      and v':
      "v'=\<lparr>ext =Abs_real_int(left(len v ts c), right (len v ts c)),
           lan = lan v,
           own = own v\<rparr>"
      and v3:
      "v3=\<lparr>ext =Abs_real_int(right(len v ts c), right (ext v)),
           lan = lan v,
           own = own v\<rparr>"
        by blast
    hence 1:" (v=v1\<parallel>v2) \<and> (v2=v'\<parallel>v3)"
      using inside hchop_def real_int.rchop_def Abs_real_int_inverse real_int.left_leq_right
        v1 v2 v' v3 len_def
      by auto
    have right:"right (ext v') = right (len v ts c)"
      by (simp add: Rep_real_int_inverse  v')
    then have right':"left ((space ts v) c) \<le> right (ext v')"
      by (metis inside len_space_left less_imp_le order_trans real_int.left_leq_right)
    have left:"left (ext v') = left (len v ts c)"
      by (simp add: Rep_real_int_inverse  v')
    then have left':"right ((space ts v) c) \<ge> left (ext v')"
      by (metis inside len_space_right less_imp_le order_trans real_int.left_leq_right)
    have inside':
      "left ((space ts v) c) < right (ext v') \<and> right ((space ts v) c) > left (ext v')"
      by (metis (no_types) left' right' antisym_conv assm inside left len_space_left
          len_space_right less_imp_le not_le real_int.left_leq_right
          real_int.length_zero_iff_borders_eq right)
    have inside'':
      "left (space ts v' c) < right (ext v') \<and> right (space ts v' c) > left (ext v')"
      using "1" hchop_def inside' sensors.space_def sensors_axioms
      by auto
    have len_v_v':"len v ts c = ext v'"
      by (metis left prod.collapse right left.rep_eq right.rep_eq Rep_real_int_inverse)
    have "left (len v ts c) = max (left (ext v)) (left ((space ts v) c)) "
      using len_v Abs_real_int_inverse Rep_real_int inside
      by auto
    with left have left_len':"left (ext v') = max (left (ext v)) (left (space ts v c))"
      by auto
    then have left_len:"left (ext v') = max (left (ext v')) (left (space ts v' c))"
      using "1"  hchop_def space_def  by fastforce
    have "right (len v ts c) = min (right (ext v)) (right ((space ts v) c))"
      using len_v Abs_real_int_inverse inside Rep_real_int by auto
    with right have right_len':
      "right (ext v') = min (right (ext v)) (right (space ts v c))"
      by auto
    then have right_len:
      "right (ext v') = min (right (ext v')) (right (space ts v' c))"
      using "1"  hchop_def space_def by fastforce
    have 2:"len v' ( ts) c = ext v'"
      by (metis left_len' right_len' len_v len_v_v' order.asym inside''
          len_def left_len right_len)
    have 3:"  \<parallel>len v' ( ts) c\<parallel> = \<parallel>len v ( ts) c\<parallel>"
      using len_left len_right hchop_def
      by (simp add: "2" len_v_v')
    then show ?thesis using 1 2 3 by blast
  qed
qed

lemma ext_eq_len_eq:
  "ext v = ext v'\<and> own v = own v' \<longrightarrow> len v ts c = len v' ts c"
  using left_space right_space sensors.len_def sensors_axioms by auto

lemma len_stable_down:"(v=v1--v2) \<longrightarrow> len v ts c = len v1 ts c"
  using ext_eq_len_eq view.vchop_def by blast

lemma len_stable_up:"(v=v1--v2) \<longrightarrow> len v ts c = len v2 ts c"
  using ext_eq_len_eq view.vchop_def by blast

lemma len_empty_subview:"\<parallel>len v ts c\<parallel> = 0 \<and> (v' \<le> v) \<longrightarrow> \<parallel>len v' ts c\<parallel> = 0"
proof
  assume assm:"\<parallel>len v ts c\<parallel> = 0 \<and> (v' \<le> v)"
  hence "\<exists>v1 v2 v3 vl vr vu vd. (v=vl\<parallel>v1) \<and> (v1=v2\<parallel>vr) \<and> (v2=vd--v3) \<and> (v3=v'--vu)" using
      somewhere_leq   by auto
  then obtain v1 v2 v3 vl vr vu vd
    where views:"(v=vl\<parallel>v1) \<and> (v1=v2\<parallel>vr) \<and> (v2=vd--v3) \<and> (v3=v'--vu)"
    by blast
  have "\<parallel>len v1 ts c\<parallel> = 0" using views assm len_empty_on_subview2 by blast
  hence "\<parallel>len v2 ts c\<parallel> = 0" using views len_empty_on_subview1 by blast
  hence "\<parallel>len v3 ts c \<parallel> = 0" using views len_stable_up by auto
  thus "\<parallel>len v' ts c \<parallel> = 0" using views len_stable_down by auto
qed

lemma view_leq_len_leq:"(ext v \<le> ext v') \<and> (own v = own v') \<and> \<parallel>len v ts c\<parallel> > 0
                          \<longrightarrow> len v ts c \<le> len v' ts c"
  using Abs_real_int_inverse  length_def length_ge_zero less_eq_real_int_def
    sensors.len_def sensors.space_def sensors_axioms by auto

end
end


(*  Title:      HOL/NSA/NSComplex.thy
    Author:     Jacques D. Fleuriot, University of Edinburgh
    Author:     Lawrence C Paulson
*)

section{*Nonstandard Complex Numbers*}

theory NSComplex
imports NSA
begin

type_synonym hcomplex = "complex star"

abbreviation
  hcomplex_of_complex :: "complex => complex star" where
  "hcomplex_of_complex == star_of"

abbreviation
  hcmod :: "complex star => real star" where
  "hcmod == hnorm"

  (*--- real and Imaginary parts ---*)

definition
  hRe :: "hcomplex => hypreal" where
  "hRe = *f* Re"

definition
  hIm :: "hcomplex => hypreal" where
  "hIm = *f* Im"

  (*------ imaginary unit ----------*)

definition
  iii :: hcomplex where
  "iii = star_of ii"

  (*------- complex conjugate ------*)

definition
  hcnj :: "hcomplex => hcomplex" where
  "hcnj = *f* cnj"

  (*------------ Argand -------------*)

definition
  hsgn :: "hcomplex => hcomplex" where
  "hsgn = *f* sgn"

definition
  harg :: "hcomplex => hypreal" where
  "harg = *f* arg"

definition
  (* abbreviation for (cos a + i sin a) *)
  hcis :: "hypreal => hcomplex" where
  "hcis = *f* cis"

  (*----- injection from hyperreals -----*)

abbreviation
  hcomplex_of_hypreal :: "hypreal \<Rightarrow> hcomplex" where
  "hcomplex_of_hypreal \<equiv> of_hypreal"

definition
  (* abbreviation for r*(cos a + i sin a) *)
  hrcis :: "[hypreal, hypreal] => hcomplex" where
  "hrcis = *f2* rcis"

  (*------------ e ^ (x + iy) ------------*)
definition
  hexpi :: "hcomplex => hcomplex" where
  "hexpi = *f* expi"

definition
  HComplex :: "[hypreal,hypreal] => hcomplex" where
  "HComplex = *f2* Complex"

lemmas hcomplex_defs [transfer_unfold] =
  hRe_def hIm_def iii_def hcnj_def hsgn_def harg_def hcis_def
  hrcis_def hexpi_def HComplex_def

lemma Standard_hRe [simp]: "x \<in> Standard \<Longrightarrow> hRe x \<in> Standard"
by (simp add: hcomplex_defs)

lemma Standard_hIm [simp]: "x \<in> Standard \<Longrightarrow> hIm x \<in> Standard"
by (simp add: hcomplex_defs)

lemma Standard_iii [simp]: "iii \<in> Standard"
by (simp add: hcomplex_defs)

lemma Standard_hcnj [simp]: "x \<in> Standard \<Longrightarrow> hcnj x \<in> Standard"
by (simp add: hcomplex_defs)

lemma Standard_hsgn [simp]: "x \<in> Standard \<Longrightarrow> hsgn x \<in> Standard"
by (simp add: hcomplex_defs)

lemma Standard_harg [simp]: "x \<in> Standard \<Longrightarrow> harg x \<in> Standard"
by (simp add: hcomplex_defs)

lemma Standard_hcis [simp]: "r \<in> Standard \<Longrightarrow> hcis r \<in> Standard"
by (simp add: hcomplex_defs)

lemma Standard_hexpi [simp]: "x \<in> Standard \<Longrightarrow> hexpi x \<in> Standard"
by (simp add: hcomplex_defs)

lemma Standard_hrcis [simp]:
  "\<lbrakk>r \<in> Standard; s \<in> Standard\<rbrakk> \<Longrightarrow> hrcis r s \<in> Standard"
by (simp add: hcomplex_defs)

lemma Standard_HComplex [simp]:
  "\<lbrakk>r \<in> Standard; s \<in> Standard\<rbrakk> \<Longrightarrow> HComplex r s \<in> Standard"
by (simp add: hcomplex_defs)

lemma hcmod_def: "hcmod = *f* cmod"
by (rule hnorm_def)

subsection{*Properties of Nonstandard Real and Imaginary Parts*}

lemma hcomplex_hRe_hIm_cancel_iff:
     "!!w z. (w=z) = (hRe(w) = hRe(z) & hIm(w) = hIm(z))"
by transfer (rule complex_Re_Im_cancel_iff)

lemma hcomplex_equality [intro?]:
  "!!z w. hRe z = hRe w ==> hIm z = hIm w ==> z = w"
by transfer (rule complex_equality)

lemma hcomplex_hRe_zero [simp]: "hRe 0 = 0"
by transfer simp

lemma hcomplex_hIm_zero [simp]: "hIm 0 = 0"
by transfer simp

lemma hcomplex_hRe_one [simp]: "hRe 1 = 1"
by transfer simp

lemma hcomplex_hIm_one [simp]: "hIm 1 = 0"
by transfer simp

subsection{*Addition for Nonstandard Complex Numbers*}

lemma hRe_add: "!!x y. hRe(x + y) = hRe(x) + hRe(y)"
by transfer simp

lemma hIm_add: "!!x y. hIm(x + y) = hIm(x) + hIm(y)"
by transfer simp

subsection{*More Minus Laws*}

lemma hRe_minus: "!!z. hRe(-z) = - hRe(z)"
by transfer (rule uminus_complex.sel)

lemma hIm_minus: "!!z. hIm(-z) = - hIm(z)"
by transfer (rule uminus_complex.sel)

lemma hcomplex_add_minus_eq_minus:
      "x + y = (0::hcomplex) ==> x = -y"
apply (drule minus_unique)
apply (simp add: minus_equation_iff [of x y])
done

lemma hcomplex_i_mult_eq [simp]: "iii * iii = -1"
by transfer (rule i_squared)

lemma hcomplex_i_mult_left [simp]: "!!z. iii * (iii * z) = -z"
by transfer (rule complex_i_mult_minus)

lemma hcomplex_i_not_zero [simp]: "iii \<noteq> 0"
by transfer (rule complex_i_not_zero)

subsection{*More Multiplication Laws*}

lemma hcomplex_mult_minus_one: "- 1 * (z::hcomplex) = -z"
by simp

lemma hcomplex_mult_minus_one_right: "(z::hcomplex) * - 1 = -z"
by simp

lemma hcomplex_mult_left_cancel:
     "(c::hcomplex) \<noteq> (0::hcomplex) ==> (c*a=c*b) = (a=b)"
by simp

lemma hcomplex_mult_right_cancel:
     "(c::hcomplex) \<noteq> (0::hcomplex) ==> (a*c=b*c) = (a=b)"
by simp

subsection{*Subraction and Division*}

lemma hcomplex_diff_eq_eq [simp]: "((x::hcomplex) - y = z) = (x = z + y)"
(* TODO: delete *)
by (rule diff_eq_eq)

subsection{*Embedding Properties for @{term hcomplex_of_hypreal} Map*}

lemma hRe_hcomplex_of_hypreal [simp]: "!!z. hRe(hcomplex_of_hypreal z) = z"
by transfer (rule Re_complex_of_real)

lemma hIm_hcomplex_of_hypreal [simp]: "!!z. hIm(hcomplex_of_hypreal z) = 0"
by transfer (rule Im_complex_of_real)

lemma hcomplex_of_hypreal_epsilon_not_zero [simp]:
     "hcomplex_of_hypreal epsilon \<noteq> 0"
by (simp add: hypreal_epsilon_not_zero)

subsection{*HComplex theorems*}

lemma hRe_HComplex [simp]: "!!x y. hRe (HComplex x y) = x"
by transfer simp

lemma hIm_HComplex [simp]: "!!x y. hIm (HComplex x y) = y"
by transfer simp

lemma hcomplex_surj [simp]: "!!z. HComplex (hRe z) (hIm z) = z"
by transfer (rule complex_surj)

lemma hcomplex_induct [case_names rect(*, induct type: hcomplex*)]:
     "(\<And>x y. P (HComplex x y)) ==> P z"
by (rule hcomplex_surj [THEN subst], blast)

subsection{*Modulus (Absolute Value) of Nonstandard Complex Number*}

lemma hcomplex_of_hypreal_abs:
     "hcomplex_of_hypreal (abs x) =
      hcomplex_of_hypreal(hcmod(hcomplex_of_hypreal x))"
by simp

lemma HComplex_inject [simp]:
  "!!x y x' y'. HComplex x y = HComplex x' y' = (x=x' & y=y')"
by transfer (rule complex.inject)

lemma HComplex_add [simp]:
  "!!x1 y1 x2 y2. HComplex x1 y1 + HComplex x2 y2 = HComplex (x1+x2) (y1+y2)"
by transfer (rule complex_add)

lemma HComplex_minus [simp]: "!!x y. - HComplex x y = HComplex (-x) (-y)"
by transfer (rule complex_minus)

lemma HComplex_diff [simp]:
  "!!x1 y1 x2 y2. HComplex x1 y1 - HComplex x2 y2 = HComplex (x1-x2) (y1-y2)"
by transfer (rule complex_diff)

lemma HComplex_mult [simp]:
  "!!x1 y1 x2 y2. HComplex x1 y1 * HComplex x2 y2 =
   HComplex (x1*x2 - y1*y2) (x1*y2 + y1*x2)"
by transfer (rule complex_mult)

(*HComplex_inverse is proved below*)

lemma hcomplex_of_hypreal_eq: "!!r. hcomplex_of_hypreal r = HComplex r 0"
by transfer (rule complex_of_real_def)

lemma HComplex_add_hcomplex_of_hypreal [simp]:
     "!!x y r. HComplex x y + hcomplex_of_hypreal r = HComplex (x+r) y"
by transfer (rule Complex_add_complex_of_real)

lemma hcomplex_of_hypreal_add_HComplex [simp]:
     "!!r x y. hcomplex_of_hypreal r + HComplex x y = HComplex (r+x) y"
by transfer (rule complex_of_real_add_Complex)

lemma HComplex_mult_hcomplex_of_hypreal:
     "!!x y r. HComplex x y * hcomplex_of_hypreal r = HComplex (x*r) (y*r)"
by transfer (rule Complex_mult_complex_of_real)

lemma hcomplex_of_hypreal_mult_HComplex:
     "!!r x y. hcomplex_of_hypreal r * HComplex x y = HComplex (r*x) (r*y)"
by transfer (rule complex_of_real_mult_Complex)

lemma i_hcomplex_of_hypreal [simp]:
     "!!r. iii * hcomplex_of_hypreal r = HComplex 0 r"
by transfer (rule i_complex_of_real)

lemma hcomplex_of_hypreal_i [simp]:
     "!!r. hcomplex_of_hypreal r * iii = HComplex 0 r"
by transfer (rule complex_of_real_i)

subsection{*Conjugation*}

lemma hcomplex_hcnj_cancel_iff [iff]: "!!x y. (hcnj x = hcnj y) = (x = y)"
by transfer (rule complex_cnj_cancel_iff)

lemma hcomplex_hcnj_hcnj [simp]: "!!z. hcnj (hcnj z) = z"
by transfer (rule complex_cnj_cnj)

lemma hcomplex_hcnj_hcomplex_of_hypreal [simp]:
     "!!x. hcnj (hcomplex_of_hypreal x) = hcomplex_of_hypreal x"
by transfer (rule complex_cnj_complex_of_real)

lemma hcomplex_hmod_hcnj [simp]: "!!z. hcmod (hcnj z) = hcmod z"
by transfer (rule complex_mod_cnj)

lemma hcomplex_hcnj_minus: "!!z. hcnj (-z) = - hcnj z"
by transfer (rule complex_cnj_minus)

lemma hcomplex_hcnj_inverse: "!!z. hcnj(inverse z) = inverse(hcnj z)"
by transfer (rule complex_cnj_inverse)

lemma hcomplex_hcnj_add: "!!w z. hcnj(w + z) = hcnj(w) + hcnj(z)"
by transfer (rule complex_cnj_add)

lemma hcomplex_hcnj_diff: "!!w z. hcnj(w - z) = hcnj(w) - hcnj(z)"
by transfer (rule complex_cnj_diff)

lemma hcomplex_hcnj_mult: "!!w z. hcnj(w * z) = hcnj(w) * hcnj(z)"
by transfer (rule complex_cnj_mult)

lemma hcomplex_hcnj_divide: "!!w z. hcnj(w / z) = (hcnj w)/(hcnj z)"
by transfer (rule complex_cnj_divide)

lemma hcnj_one [simp]: "hcnj 1 = 1"
by transfer (rule complex_cnj_one)

lemma hcomplex_hcnj_zero [simp]: "hcnj 0 = 0"
by transfer (rule complex_cnj_zero)

lemma hcomplex_hcnj_zero_iff [iff]: "!!z. (hcnj z = 0) = (z = 0)"
by transfer (rule complex_cnj_zero_iff)

lemma hcomplex_mult_hcnj:
     "!!z. z * hcnj z = hcomplex_of_hypreal ((hRe z)\<^sup>2 + (hIm z)\<^sup>2)"
by transfer (rule complex_mult_cnj)

subsection{*More Theorems about the Function @{term hcmod}*}

lemma hcmod_hcomplex_of_hypreal_of_nat [simp]:
     "hcmod (hcomplex_of_hypreal(hypreal_of_nat n)) = hypreal_of_nat n"
by simp

lemma hcmod_hcomplex_of_hypreal_of_hypnat [simp]:
     "hcmod (hcomplex_of_hypreal(hypreal_of_hypnat n)) = hypreal_of_hypnat n"
by simp

lemma hcmod_mult_hcnj: "!!z. hcmod(z * hcnj(z)) = (hcmod z)\<^sup>2"
by transfer (rule complex_mod_mult_cnj)

lemma hcmod_triangle_ineq2 [simp]:
  "!!a b. hcmod(b + a) - hcmod b \<le> hcmod a"
by transfer (rule complex_mod_triangle_ineq2)

lemma hcmod_diff_ineq [simp]: "!!a b. hcmod(a) - hcmod(b) \<le> hcmod(a + b)"
by transfer (rule norm_diff_ineq)

subsection{*Exponentiation*}

lemma hcomplexpow_0 [simp]:   "z ^ 0       = (1::hcomplex)"
by (rule power_0)

lemma hcomplexpow_Suc [simp]: "z ^ (Suc n) = (z::hcomplex) * (z ^ n)"
by (rule power_Suc)

lemma hcomplexpow_i_squared [simp]: "iii\<^sup>2 = -1"
by transfer (rule power2_i)

lemma hcomplex_of_hypreal_pow:
     "!!x. hcomplex_of_hypreal (x ^ n) = (hcomplex_of_hypreal x) ^ n"
by transfer (rule of_real_power)

lemma hcomplex_hcnj_pow: "!!z. hcnj(z ^ n) = hcnj(z) ^ n"
by transfer (rule complex_cnj_power)

lemma hcmod_hcomplexpow: "!!x. hcmod(x ^ n) = hcmod(x) ^ n"
by transfer (rule norm_power)

lemma hcpow_minus:
     "!!x n. (-x::hcomplex) pow n =
      (if ( *p* even) n then (x pow n) else -(x pow n))"
by transfer simp

lemma hcpow_mult:
  "!!r s n. ((r::hcomplex) * s) pow n = (r pow n) * (s pow n)"
  by (fact hyperpow_mult)

lemma hcpow_zero2 [simp]:
  "\<And>n. 0 pow (hSuc n) = (0::'a::{power,semiring_0} star)"
by transfer (rule power_0_Suc)

lemma hcpow_not_zero [simp,intro]:
  "!!r n. r \<noteq> 0 ==> r pow n \<noteq> (0::hcomplex)"
by (rule hyperpow_not_zero)

lemma hcpow_zero_zero: "r pow n = (0::hcomplex) ==> r = 0"
by (blast intro: ccontr dest: hcpow_not_zero)

subsection{*The Function @{term hsgn}*}

lemma hsgn_zero [simp]: "hsgn 0 = 0"
by transfer (rule sgn_zero)

lemma hsgn_one [simp]: "hsgn 1 = 1"
by transfer (rule sgn_one)

lemma hsgn_minus: "!!z. hsgn (-z) = - hsgn(z)"
by transfer (rule sgn_minus)

lemma hsgn_eq: "!!z. hsgn z = z / hcomplex_of_hypreal (hcmod z)"
by transfer (rule sgn_eq)

lemma hcmod_i: "!!x y. hcmod (HComplex x y) = ( *f* sqrt) (x\<^sup>2 + y\<^sup>2)"
by transfer (rule complex_norm)

lemma hcomplex_eq_cancel_iff1 [simp]:
     "(hcomplex_of_hypreal xa = HComplex x y) = (xa = x & y = 0)"
by (simp add: hcomplex_of_hypreal_eq)

lemma hcomplex_eq_cancel_iff2 [simp]:
     "(HComplex x y = hcomplex_of_hypreal xa) = (x = xa & y = 0)"
by (simp add: hcomplex_of_hypreal_eq)

lemma HComplex_eq_0 [simp]: "!!x y. (HComplex x y = 0) = (x = 0 & y = 0)"
by transfer (rule Complex_eq_0)

lemma HComplex_eq_1 [simp]: "!!x y. (HComplex x y = 1) = (x = 1 & y = 0)"
by transfer (rule Complex_eq_1)

lemma i_eq_HComplex_0_1: "iii = HComplex 0 1"
by transfer (simp add: complex_eq_iff)

lemma HComplex_eq_i [simp]: "!!x y. (HComplex x y = iii) = (x = 0 & y = 1)"
by transfer (rule Complex_eq_i)

lemma hRe_hsgn [simp]: "!!z. hRe(hsgn z) = hRe(z)/hcmod z"
by transfer (rule Re_sgn)

lemma hIm_hsgn [simp]: "!!z. hIm(hsgn z) = hIm(z)/hcmod z"
by transfer (rule Im_sgn)

lemma HComplex_inverse:
     "!!x y. inverse (HComplex x y) = HComplex (x/(x\<^sup>2 + y\<^sup>2)) (-y/(x\<^sup>2 + y\<^sup>2))"
by transfer (rule complex_inverse)

lemma hRe_mult_i_eq[simp]:
    "!!y. hRe (iii * hcomplex_of_hypreal y) = 0"
by transfer simp

lemma hIm_mult_i_eq [simp]:
    "!!y. hIm (iii * hcomplex_of_hypreal y) = y"
by transfer simp

lemma hcmod_mult_i [simp]: "!!y. hcmod (iii * hcomplex_of_hypreal y) = abs y"
by transfer (simp add: norm_complex_def)

lemma hcmod_mult_i2 [simp]: "!!y. hcmod (hcomplex_of_hypreal y * iii) = abs y"
by transfer (simp add: norm_complex_def)

(*---------------------------------------------------------------------------*)
(*  harg                                                                     *)
(*---------------------------------------------------------------------------*)

lemma cos_harg_i_mult_zero [simp]:
     "!!y. y \<noteq> 0 ==> ( *f* cos) (harg(HComplex 0 y)) = 0"
by transfer simp

lemma hcomplex_of_hypreal_zero_iff [simp]:
     "!!y. (hcomplex_of_hypreal y = 0) = (y = 0)"
by transfer (rule of_real_eq_0_iff)

subsection{*Polar Form for Nonstandard Complex Numbers*}

lemma complex_split_polar2:
     "\<forall>n. \<exists>r a. (z n) =  complex_of_real r * (Complex (cos a) (sin a))"
by (auto intro: complex_split_polar)

lemma hcomplex_split_polar:
  "!!z. \<exists>r a. z = hcomplex_of_hypreal r * (HComplex(( *f* cos) a)(( *f* sin) a))"
by transfer (simp add: complex_split_polar)

lemma hcis_eq:
   "!!a. hcis a =
    (hcomplex_of_hypreal(( *f* cos) a) +
    iii * hcomplex_of_hypreal(( *f* sin) a))"
by transfer (simp add: complex_eq_iff)

lemma hrcis_Ex: "!!z. \<exists>r a. z = hrcis r a"
by transfer (rule rcis_Ex)

lemma hRe_hcomplex_polar [simp]:
  "!!r a. hRe (hcomplex_of_hypreal r * HComplex (( *f* cos) a) (( *f* sin) a)) =
      r * ( *f* cos) a"
by transfer simp

lemma hRe_hrcis [simp]: "!!r a. hRe(hrcis r a) = r * ( *f* cos) a"
by transfer (rule Re_rcis)

lemma hIm_hcomplex_polar [simp]:
  "!!r a. hIm (hcomplex_of_hypreal r * HComplex (( *f* cos) a) (( *f* sin) a)) =
      r * ( *f* sin) a"
by transfer simp

lemma hIm_hrcis [simp]: "!!r a. hIm(hrcis r a) = r * ( *f* sin) a"
by transfer (rule Im_rcis)

lemma hcmod_unit_one [simp]:
     "!!a. hcmod (HComplex (( *f* cos) a) (( *f* sin) a)) = 1"
by transfer (simp add: cmod_unit_one)

lemma hcmod_complex_polar [simp]:
  "!!r a. hcmod (hcomplex_of_hypreal r * HComplex (( *f* cos) a) (( *f* sin) a)) =
      abs r"
by transfer (simp add: cmod_complex_polar)

lemma hcmod_hrcis [simp]: "!!r a. hcmod(hrcis r a) = abs r"
by transfer (rule complex_mod_rcis)

(*---------------------------------------------------------------------------*)
(*  (r1 * hrcis a) * (r2 * hrcis b) = r1 * r2 * hrcis (a + b)                *)
(*---------------------------------------------------------------------------*)

lemma hcis_hrcis_eq: "!!a. hcis a = hrcis 1 a"
by transfer (rule cis_rcis_eq)
declare hcis_hrcis_eq [symmetric, simp]

lemma hrcis_mult:
  "!!a b r1 r2. hrcis r1 a * hrcis r2 b = hrcis (r1*r2) (a + b)"
by transfer (rule rcis_mult)

lemma hcis_mult: "!!a b. hcis a * hcis b = hcis (a + b)"
by transfer (rule cis_mult)

lemma hcis_zero [simp]: "hcis 0 = 1"
by transfer (rule cis_zero)

lemma hrcis_zero_mod [simp]: "!!a. hrcis 0 a = 0"
by transfer (rule rcis_zero_mod)

lemma hrcis_zero_arg [simp]: "!!r. hrcis r 0 = hcomplex_of_hypreal r"
by transfer (rule rcis_zero_arg)

lemma hcomplex_i_mult_minus [simp]: "!!x. iii * (iii * x) = - x"
by transfer (rule complex_i_mult_minus)

lemma hcomplex_i_mult_minus2 [simp]: "iii * iii * x = - x"
by simp

lemma hcis_hypreal_of_nat_Suc_mult:
   "!!a. hcis (hypreal_of_nat (Suc n) * a) =
     hcis a * hcis (hypreal_of_nat n * a)"
apply transfer
apply (simp add: distrib_right cis_mult)
done

lemma NSDeMoivre: "!!a. (hcis a) ^ n = hcis (hypreal_of_nat n * a)"
apply transfer
apply (fold real_of_nat_def)
apply (rule DeMoivre)
done

lemma hcis_hypreal_of_hypnat_Suc_mult:
     "!! a n. hcis (hypreal_of_hypnat (n + 1) * a) =
      hcis a * hcis (hypreal_of_hypnat n * a)"
by transfer (simp add: distrib_right cis_mult)

lemma NSDeMoivre_ext:
  "!!a n. (hcis a) pow n = hcis (hypreal_of_hypnat n * a)"
by transfer (fold real_of_nat_def, rule DeMoivre)

lemma NSDeMoivre2:
  "!!a r. (hrcis r a) ^ n = hrcis (r ^ n) (hypreal_of_nat n * a)"
by transfer (fold real_of_nat_def, rule DeMoivre2)

lemma DeMoivre2_ext:
  "!! a r n. (hrcis r a) pow n = hrcis (r pow n) (hypreal_of_hypnat n * a)"
by transfer (fold real_of_nat_def, rule DeMoivre2)

lemma hcis_inverse [simp]: "!!a. inverse(hcis a) = hcis (-a)"
by transfer (rule cis_inverse)

lemma hrcis_inverse: "!!a r. inverse(hrcis r a) = hrcis (inverse r) (-a)"
by transfer (simp add: rcis_inverse inverse_eq_divide [symmetric])

lemma hRe_hcis [simp]: "!!a. hRe(hcis a) = ( *f* cos) a"
by transfer simp

lemma hIm_hcis [simp]: "!!a. hIm(hcis a) = ( *f* sin) a"
by transfer simp

lemma cos_n_hRe_hcis_pow_n: "( *f* cos) (hypreal_of_nat n * a) = hRe(hcis a ^ n)"
by (simp add: NSDeMoivre)

lemma sin_n_hIm_hcis_pow_n: "( *f* sin) (hypreal_of_nat n * a) = hIm(hcis a ^ n)"
by (simp add: NSDeMoivre)

lemma cos_n_hRe_hcis_hcpow_n: "( *f* cos) (hypreal_of_hypnat n * a) = hRe(hcis a pow n)"
by (simp add: NSDeMoivre_ext)

lemma sin_n_hIm_hcis_hcpow_n: "( *f* sin) (hypreal_of_hypnat n * a) = hIm(hcis a pow n)"
by (simp add: NSDeMoivre_ext)

lemma hexpi_add: "!!a b. hexpi(a + b) = hexpi(a) * hexpi(b)"
by transfer (rule exp_add)

subsection{*@{term hcomplex_of_complex}: the Injection from
  type @{typ complex} to to @{typ hcomplex}*}

lemma inj_hcomplex_of_complex: "inj(hcomplex_of_complex)"
(* TODO: delete *)
by (rule inj_star_of)

lemma hcomplex_of_complex_i: "iii = hcomplex_of_complex ii"
by (rule iii_def)

lemma hRe_hcomplex_of_complex:
   "hRe (hcomplex_of_complex z) = hypreal_of_real (Re z)"
by transfer (rule refl)

lemma hIm_hcomplex_of_complex:
   "hIm (hcomplex_of_complex z) = hypreal_of_real (Im z)"
by transfer (rule refl)

lemma hcmod_hcomplex_of_complex:
     "hcmod (hcomplex_of_complex x) = hypreal_of_real (cmod x)"
by transfer (rule refl)

subsection{*Numerals and Arithmetic*}

lemma hcomplex_of_hypreal_eq_hcomplex_of_complex:
     "hcomplex_of_hypreal (hypreal_of_real x) =
      hcomplex_of_complex (complex_of_real x)"
by transfer (rule refl)

lemma hcomplex_hypreal_numeral:
  "hcomplex_of_complex (numeral w) = hcomplex_of_hypreal(numeral w)"
by transfer (rule of_real_numeral [symmetric])

lemma hcomplex_hypreal_neg_numeral:
  "hcomplex_of_complex (- numeral w) = hcomplex_of_hypreal(- numeral w)"
by transfer (rule of_real_neg_numeral [symmetric])

lemma hcomplex_numeral_hcnj [simp]:
     "hcnj (numeral v :: hcomplex) = numeral v"
by transfer (rule complex_cnj_numeral)

lemma hcomplex_numeral_hcmod [simp]:
      "hcmod(numeral v :: hcomplex) = (numeral v :: hypreal)"
by transfer (rule norm_numeral)

lemma hcomplex_neg_numeral_hcmod [simp]:
      "hcmod(- numeral v :: hcomplex) = (numeral v :: hypreal)"
by transfer (rule norm_neg_numeral)

lemma hcomplex_numeral_hRe [simp]:
      "hRe(numeral v :: hcomplex) = numeral v"
by transfer (rule complex_Re_numeral)

lemma hcomplex_numeral_hIm [simp]:
      "hIm(numeral v :: hcomplex) = 0"
by transfer (rule complex_Im_numeral)

(* TODO: add neg_numeral rules above *)
end