3075 by (simp add: nth_Cons') |
3075 by (simp add: nth_Cons') |
3076 |
3076 |
3077 |
3077 |
3078 subsubsection {* @{text upto}: interval-list on @{typ int} *} |
3078 subsubsection {* @{text upto}: interval-list on @{typ int} *} |
3079 |
3079 |
3080 (* FIXME make upto tail recursive? *) |
|
3081 |
|
3082 function upto :: "int \<Rightarrow> int \<Rightarrow> int list" ("(1[_../_])") where |
3080 function upto :: "int \<Rightarrow> int \<Rightarrow> int list" ("(1[_../_])") where |
3083 "upto i j = (if i \<le> j then i # [i+1..j] else [])" |
3081 "upto i j = (if i \<le> j then i # [i+1..j] else [])" |
3084 by auto |
3082 by auto |
3085 termination |
3083 termination |
3086 by(relation "measure(%(i::int,j). nat(j - i + 1))") auto |
3084 by(relation "measure(%(i::int,j). nat(j - i + 1))") auto |
3087 |
3085 |
3088 declare upto.simps[code, simp del] |
3086 declare upto.simps[simp del] |
3089 |
3087 |
3090 lemmas upto_rec_numeral [simp] = |
3088 lemmas upto_rec_numeral [simp] = |
3091 upto.simps[of "numeral m" "numeral n"] |
3089 upto.simps[of "numeral m" "numeral n"] |
3092 upto.simps[of "numeral m" "neg_numeral n"] |
3090 upto.simps[of "numeral m" "neg_numeral n"] |
3093 upto.simps[of "neg_numeral m" "numeral n"] |
3091 upto.simps[of "neg_numeral m" "numeral n"] |
3094 upto.simps[of "neg_numeral m" "neg_numeral n"] for m n |
3092 upto.simps[of "neg_numeral m" "neg_numeral n"] for m n |
3095 |
3093 |
3096 lemma upto_empty[simp]: "j < i \<Longrightarrow> [i..j] = []" |
3094 lemma upto_empty[simp]: "j < i \<Longrightarrow> [i..j] = []" |
3097 by(simp add: upto.simps) |
3095 by(simp add: upto.simps) |
3098 |
3096 |
|
3097 lemma upto_rec1: "i \<le> j \<Longrightarrow> [i..j] = i#[i+1..j]" |
|
3098 by(simp add: upto.simps) |
|
3099 |
|
3100 lemma upto_rec2: "i \<le> j \<Longrightarrow> [i..j] = [i..j - 1]@[j]" |
|
3101 proof(induct "nat(j-i)" arbitrary: i j) |
|
3102 case 0 thus ?case by(simp add: upto.simps) |
|
3103 next |
|
3104 case (Suc n) |
|
3105 hence "n = nat (j - (i + 1))" "i < j" by linarith+ |
|
3106 from this(2) Suc.hyps(1)[OF this(1)] Suc(2,3) upto_rec1 show ?case by simp |
|
3107 qed |
|
3108 |
3099 lemma set_upto[simp]: "set[i..j] = {i..j}" |
3109 lemma set_upto[simp]: "set[i..j] = {i..j}" |
3100 proof(induct i j rule:upto.induct) |
3110 proof(induct i j rule:upto.induct) |
3101 case (1 i j) |
3111 case (1 i j) |
3102 from this show ?case |
3112 from this show ?case |
3103 unfolding upto.simps[of i j] simp_from_to[of i j] by auto |
3113 unfolding upto.simps[of i j] simp_from_to[of i j] by auto |
3104 qed |
3114 qed |
|
3115 |
|
3116 text{* Tail recursive version for code generation: *} |
|
3117 |
|
3118 function upto_aux :: "int \<Rightarrow> int \<Rightarrow> int list \<Rightarrow> int list" where |
|
3119 "upto_aux i j js = (if j<i then js else upto_aux i (j - 1) (j#js))" |
|
3120 by auto |
|
3121 termination by(relation "measure(%(i::int,j,js). nat(j - i + 1))") auto |
|
3122 |
|
3123 lemma upto_aux_upto: "upto_aux i j js = [i..j] @ js" |
|
3124 proof cases |
|
3125 assume "j < i" thus ?thesis by(simp) |
|
3126 next |
|
3127 assume "\<not> j < i" |
|
3128 thus ?thesis |
|
3129 proof(induct i j js rule: upto_aux.induct) |
|
3130 case 1 thus ?case using upto_rec2 by simp |
|
3131 qed |
|
3132 qed |
|
3133 |
|
3134 declare upto_aux.simps[simp del] |
|
3135 |
|
3136 lemma upto_code[code]: "[i..j] = upto_aux i j []" |
|
3137 by(simp add: upto_aux_upto) |
3105 |
3138 |
3106 |
3139 |
3107 subsubsection {* @{const distinct} and @{const remdups} *} |
3140 subsubsection {* @{const distinct} and @{const remdups} *} |
3108 |
3141 |
3109 lemma distinct_tl: |
3142 lemma distinct_tl: |