src/HOL/Imperative_HOL/ex/Imperative_Reverse.thy
changeset 40671 5e46057ba8e0
parent 38069 7775fdc52b6d
child 44890 22f665a2e91c
equal deleted inserted replaced
40630:3b5c31e55540 40671:5e46057ba8e0
    24    }
    24    }
    25    else return ())"
    25    else return ())"
    26 
    26 
    27 declare swap.simps [simp del] rev.simps [simp del]
    27 declare swap.simps [simp del] rev.simps [simp del]
    28 
    28 
    29 lemma swap_pointwise: assumes "crel (swap a i j) h h' r"
    29 lemma swap_pointwise: assumes "effect (swap a i j) h h' r"
    30   shows "Array.get h' a ! k = (if k = i then Array.get h a ! j
    30   shows "Array.get h' a ! k = (if k = i then Array.get h a ! j
    31       else if k = j then Array.get h a ! i
    31       else if k = j then Array.get h a ! i
    32       else Array.get h a ! k)"
    32       else Array.get h a ! k)"
    33 using assms unfolding swap.simps
    33 using assms unfolding swap.simps
    34 by (elim crel_elims)
    34 by (elim effect_elims)
    35  (auto simp: length_def)
    35  (auto simp: length_def)
    36 
    36 
    37 lemma rev_pointwise: assumes "crel (rev a i j) h h' r"
    37 lemma rev_pointwise: assumes "effect (rev a i j) h h' r"
    38   shows "Array.get h' a ! k = (if k < i then Array.get h a ! k
    38   shows "Array.get h' a ! k = (if k < i then Array.get h a ! k
    39       else if j < k then Array.get h a ! k
    39       else if j < k then Array.get h a ! k
    40       else Array.get h a ! (j - (k - i)))" (is "?P a i j h h'")
    40       else Array.get h a ! (j - (k - i)))" (is "?P a i j h h'")
    41 using assms proof (induct a i j arbitrary: h h' rule: rev.induct)
    41 using assms proof (induct a i j arbitrary: h h' rule: rev.induct)
    42   case (1 a i j h h'')
    42   case (1 a i j h h'')
    43   thus ?case
    43   thus ?case
    44   proof (cases "i < j")
    44   proof (cases "i < j")
    45     case True
    45     case True
    46     with 1[unfolded rev.simps[of a i j]]
    46     with 1[unfolded rev.simps[of a i j]]
    47     obtain h' where
    47     obtain h' where
    48       swp: "crel (swap a i j) h h' ()"
    48       swp: "effect (swap a i j) h h' ()"
    49       and rev: "crel (rev a (i + 1) (j - 1)) h' h'' ()"
    49       and rev: "effect (rev a (i + 1) (j - 1)) h' h'' ()"
    50       by (auto elim: crel_elims)
    50       by (auto elim: effect_elims)
    51     from rev 1 True
    51     from rev 1 True
    52     have eq: "?P a (i + 1) (j - 1) h' h''" by auto
    52     have eq: "?P a (i + 1) (j - 1) h' h''" by auto
    53 
    53 
    54     have "k < i \<or> i = k \<or> (i < k \<and> k < j) \<or> j = k \<or> j < k" by arith
    54     have "k < i \<or> i = k \<or> (i < k \<and> k < j) \<or> j = k \<or> j < k" by arith
    55     with True show ?thesis
    55     with True show ?thesis
    56       by (elim disjE) (auto simp: eq swap_pointwise[OF swp])
    56       by (elim disjE) (auto simp: eq swap_pointwise[OF swp])
    57   next
    57   next
    58     case False
    58     case False
    59     with 1[unfolded rev.simps[of a i j]]
    59     with 1[unfolded rev.simps[of a i j]]
    60     show ?thesis
    60     show ?thesis
    61       by (cases "k = j") (auto elim: crel_elims)
    61       by (cases "k = j") (auto elim: effect_elims)
    62   qed
    62   qed
    63 qed
    63 qed
    64 
    64 
    65 lemma rev_length:
    65 lemma rev_length:
    66   assumes "crel (rev a i j) h h' r"
    66   assumes "effect (rev a i j) h h' r"
    67   shows "Array.length h a = Array.length h' a"
    67   shows "Array.length h a = Array.length h' a"
    68 using assms
    68 using assms
    69 proof (induct a i j arbitrary: h h' rule: rev.induct)
    69 proof (induct a i j arbitrary: h h' rule: rev.induct)
    70   case (1 a i j h h'')
    70   case (1 a i j h h'')
    71   thus ?case
    71   thus ?case
    72   proof (cases "i < j")
    72   proof (cases "i < j")
    73     case True
    73     case True
    74     with 1[unfolded rev.simps[of a i j]]
    74     with 1[unfolded rev.simps[of a i j]]
    75     obtain h' where
    75     obtain h' where
    76       swp: "crel (swap a i j) h h' ()"
    76       swp: "effect (swap a i j) h h' ()"
    77       and rev: "crel (rev a (i + 1) (j - 1)) h' h'' ()"
    77       and rev: "effect (rev a (i + 1) (j - 1)) h' h'' ()"
    78       by (auto elim: crel_elims)
    78       by (auto elim: effect_elims)
    79     from swp rev 1 True show ?thesis
    79     from swp rev 1 True show ?thesis
    80       unfolding swap.simps
    80       unfolding swap.simps
    81       by (elim crel_elims) fastsimp
    81       by (elim effect_elims) fastsimp
    82   next
    82   next
    83     case False
    83     case False
    84     with 1[unfolded rev.simps[of a i j]]
    84     with 1[unfolded rev.simps[of a i j]]
    85     show ?thesis
    85     show ?thesis
    86       by (auto elim: crel_elims)
    86       by (auto elim: effect_elims)
    87   qed
    87   qed
    88 qed
    88 qed
    89 
    89 
    90 lemma rev2_rev': assumes "crel (rev a i j) h h' u"
    90 lemma rev2_rev': assumes "effect (rev a i j) h h' u"
    91   assumes "j < Array.length h a"
    91   assumes "j < Array.length h a"
    92   shows "subarray i (j + 1) a h' = List.rev (subarray i (j + 1) a h)"
    92   shows "subarray i (j + 1) a h' = List.rev (subarray i (j + 1) a h)"
    93 proof - 
    93 proof - 
    94   {
    94   {
    95     fix k
    95     fix k
   101   unfolding subarray_def Array.length_def
   101   unfolding subarray_def Array.length_def
   102   by (auto simp add: length_sublist' rev_nth min_def nth_sublist' intro!: nth_equalityI)
   102   by (auto simp add: length_sublist' rev_nth min_def nth_sublist' intro!: nth_equalityI)
   103 qed
   103 qed
   104 
   104 
   105 lemma rev2_rev: 
   105 lemma rev2_rev: 
   106   assumes "crel (rev a 0 (Array.length h a - 1)) h h' u"
   106   assumes "effect (rev a 0 (Array.length h a - 1)) h h' u"
   107   shows "Array.get h' a = List.rev (Array.get h a)"
   107   shows "Array.get h' a = List.rev (Array.get h a)"
   108   using rev2_rev'[OF assms] rev_length[OF assms] assms
   108   using rev2_rev'[OF assms] rev_length[OF assms] assms
   109     by (cases "Array.length h a = 0", auto simp add: Array.length_def
   109     by (cases "Array.length h a = 0", auto simp add: Array.length_def
   110       subarray_def sublist'_all rev.simps[where j=0] elim!: crel_elims)
   110       subarray_def sublist'_all rev.simps[where j=0] elim!: effect_elims)
   111   (drule sym[of "List.length (Array.get h a)"], simp)
   111   (drule sym[of "List.length (Array.get h a)"], simp)
   112 
   112 
   113 definition "example = (Array.make 10 id \<guillemotright>= (\<lambda>a. rev a 0 9))"
   113 definition "example = (Array.make 10 id \<guillemotright>= (\<lambda>a. rev a 0 9))"
   114 
   114 
   115 export_code example checking SML SML_imp OCaml? OCaml_imp? Haskell? Scala? Scala_imp?
   115 export_code example checking SML SML_imp OCaml? OCaml_imp? Haskell? Scala? Scala_imp?