fun plus_nat_tm :: "nat ==> nat ==> nat tm"where "plus_nat_tm (Suc m) n =1 plus_nat_tm m (Suc n)"
| "plus_nat_tm 0 n =1 return n"
lemma val_plus_nat_tm[simp, val_simp]: "val (plus_nat_tm m n) = m + n" by (induction m n rule: plus_nat_tm.induct) simp_all
lemma time_plus_nat_tm[simp]: "time (plus_nat_tm m n) = m + 1" by (induction m n rule: plus_nat_tm.induct) simp_all
subsubsection"@{const times}"
fun times_nat_tm :: "nat ==> nat ==> nat tm"where "times_nat_tm 0 n =1 return 0"
| "times_nat_tm (Suc m) n =1 do { r ← times_nat_tm m n; plus_nat_tm n r }"
lemma val_times_nat_tm[simp]: "val (times_nat_tm m n) = m * n" by (induction m n rule: times_nat_tm.induct) simp_all
lemma time_times_nat_tm[simp]: "time (times_nat_tm m n) = m * (n + 2) + 1" by (induction m n rule: times_nat_tm.induct) simp_all
subsubsection"@{const power}"
fun power_nat_tm :: "nat ==> nat ==> nat tm"where "power_nat_tm a 0 =1 return 1"
| "power_nat_tm a (Suc n) =1 do { r ← power_nat_tm a n; times_nat_tm a r }"
lemma val_power_nat_tm[simp, val_simp]: "val (power_nat_tm a n) = a ^ n" by (induction a n rule: power_nat_tm.induct) simp_all
lemma time_power_nat_tm_aux0: "time (power_nat_tm 0 n) = 2 * n + 1" by (induction n) simp_all
lemma time_power_nat_tm_aux1: "time (power_nat_tm 1 n) = 5 * n + 1" by (induction n) simp_all
lemma time_power_nat_tm_aux2: assumes"m ≥ 2" shows"time (power_nat_tm m n) ≤ (2 * n + m ^ n) * m + 2 * n + 1" proof (induction n) case0 thenhave"time (power_nat_tm m 0) = 1"by simp thenshow ?caseby simp next case (Suc n) have"time (power_nat_tm m (Suc n)) ≤ time (power_nat_tm m n) + (m ^ n + 2) * m + 2" by simp alsohave"... ≤ (2 * n + m ^ n) * m + 2 * n + 1 + (m ^ n + 2) * m + 2" using Suc by simp alsohave"... = (2 * n + m ^ n) * m + (m ^ n + 2) * m + 2 * Suc n + 1" by simp alsohave"... = (2 * Suc n + 2 * m ^ n) * m + 2 * Suc n + 1" using add_mult_distrib by simp alsohave"... ≤ (2 * Suc n + m ^ Suc n) * m + 2 * Suc n + 1" using assms by simp finallyshow ?case . qed
lemma time_power_nat_tm_le: "time (power_nat_tm m n) ≤ 3 * m ^ Suc n + 5 * n + 1" proof -
consider "m = 0" | "m = 1" | "m ≥ 2"by linarith thenshow ?thesis proof cases case1 thenshow ?thesis using time_power_nat_tm_aux0[of n] by simp next case2 thenshow ?thesis using time_power_nat_tm_aux1[of n] by simp next case3 thenhave"2 ^ n ≤ m ^ n"using power_mono by fast moreoverhave"n < 2 ^ n"by simp ultimatelyhave n_le_m_pow_n: "n ≤ m ^ n"by linarith have"time (power_nat_tm m n) ≤ (2 * m ^ n + m ^ n) * m + 2 * n + 1" apply (estimation estimate: time_power_nat_tm_aux2[OF 3, of n]) using n_le_m_pow_n by simp alsohave"... = 3 * m ^ Suc n + 2 * n + 1"by simp finallyshow ?thesis by simp qed qed
lemma time_power_nat_tm_2_le: "time (power_nat_tm 2 n) ≤ 12 * 2 ^ n" proof - have"time (power_nat_tm 2 n) ≤ 3 * 2 ^ Suc n + 5 * n + 1" by (fact time_power_nat_tm_le) alsohave"... ≤ 3 * 2 ^ Suc n + 5 * 2 ^ n + 2 ^ n" apply (intro add_mono mult_le_mono order.refl) using less_exp[of n] by simp_all finallyshow ?thesis by simp qed
subsubsection"@{const minus}"
fun minus_nat_tm :: "nat ==> nat ==> nat tm"where "minus_nat_tm m 0 =1 return m"
| "minus_nat_tm 0 m =1 return 0"
| "minus_nat_tm (Suc m) (Suc n) =1 minus_nat_tm m n"
lemma val_minus_nat_tm[simp, val_simp]: "val (minus_nat_tm m n) = m - n" by (induction m n rule: minus_nat_tm.induct) simp_all
lemma time_minus_nat_tm[simp]: "time (minus_nat_tm m n) = min m n + 1" by (induction m n rule: minus_nat_tm.induct) simp_all
subsubsection"@{const less} / @{const less_eq}"
fun less_eq_nat_tm :: "nat ==> nat ==> bool tm"and less_nat_tm :: "nat ==> nat ==> bool tm"where "less_eq_nat_tm (Suc m) n =1 less_nat_tm m n"
| "less_eq_nat_tm 0 n =1 return True"
| "less_nat_tm m (Suc n) =1 less_eq_nat_tm m n"
| "less_nat_tm m 0 =1 return False"
lemma val_less_eq_nat_tm[simp, val_simp]: "(val (less_eq_nat_tm n m) = (n ≤ m))" and val_less_nat_tm[simp, val_simp]: "(val (less_nat_tm m n) = (m < n))" by (induction m and n rule: less_eq_nat_tm_less_nat_tm.induct) auto
lemma time_less_eq_nat_tm_aux: "time (less_eq_nat_tm (m + k) (n + k)) = 2 * k + time (less_eq_nat_tm m n)" by (induction k) simp_all lemma time_less_nat_tm_aux: "time (less_nat_tm (m + k) (n + k)) = 2 * k + time (less_nat_tm m n)" by (induction k) simp_all
lemma time_less_eq_nat_tm: "time (less_eq_nat_tm n m) = 2 * min n m + 1 + of_bool (m < n)" proof (cases "m < n") case True thenobtain k where"n = m + Suc k"by (metis add_Suc_right less_natE) thenhave"time (less_eq_nat_tm n m) = 2 * m + 2" using time_less_eq_nat_tm_aux[of "Suc k" m 0] by (simp add: add.commute) thenshow ?thesis using True by simp next case False thenobtain k where"m = n + k"using nat_le_iff_add[of n m] by auto thenhave"time (less_eq_nat_tm n m) = 2 * n + 1" using time_less_eq_nat_tm_aux[of 0 n k] by (simp add: add.commute) thenshow ?thesis using False by simp qed lemma time_less_nat_tm: "time (less_nat_tm m n) = 2 * min m n + 1 + of_bool (m < n)" proof (cases "m < n") case True thenobtain k where"n = m + Suc k"by (metis add_Suc_right less_natE) thenhave"time (less_nat_tm m n) = 2 * m + 2" using time_less_nat_tm_aux[of 0 m "Suc k"] by (simp add: add.commute) thenshow ?thesis using True by simp next case False thenobtain k where"m = n + k"using nat_le_iff_add[of n m] by auto thenhave"time (less_nat_tm m n) = 2 * n + 1" using time_less_nat_tm_aux[of k n 0] by (simp add: add.commute) thenshow ?thesis using False by simp qed
lemma time_less_eq_nat_tm_le: "time (less_eq_nat_tm n m) ≤ 2 * min n m + 2" by (simp add: time_less_eq_nat_tm) lemma time_less_nat_tm_le: "time (less_nat_tm m n) ≤ 2 * min m n + 2" by (simp add: time_less_nat_tm)
lemma val_equal_nat_tm[simp, val_simp]: "val (equal_nat_tm x y) = (x = y)" by (induction x y rule: equal_nat_tm.induct) simp_all
lemma time_equal_nat_tm: "time (equal_nat_tm x y) = min x y + 1" by (induction x y rule: equal_nat_tm.induct) simp_all
subsubsection"@{const max}"
fun max_nat_tm :: "nat ==> nat ==> nat tm"where "max_nat_tm x y =1 do { b ← less_eq_nat_tm x y; if b then return y else return x }"
lemma val_max_nat_tm[simp, val_simp]: "val (max_nat_tm x y) = max x y" by simp
lemma time_max_nat_tm: "time (max_nat_tm x y) = 2 * min x y + 2 + of_bool (y < x)" by (simp add: time_less_eq_nat_tm)
lemma time_max_nat_tm_le: "time (max_nat_tm x y) ≤ 2 * min x y + 3" unfolding time_max_nat_tm by simp
subsubsection"@{const divide} / @{const modulo}"
fun divmod_nat_tm :: "nat ==> nat ==> (nat × nat) tm"where "divmod_nat_tm m n =1 do { n0 ← equal_nat_tm n 0; m_lt_n ← less_nat_tm m n; b ← disj_tm n0 m_lt_n; if b then return (0, m) else do { m_minus_n ← minus_nat_tm m n; (q, r) ← divmod_nat_tm m_minus_n n; return (Suc q, r) } }" declare divmod_nat_tm.simps[simp del]
lemma val_divmod_nat_tm[simp, val_simp]: "val (divmod_nat_tm m n) = Euclidean_Rings.divmod_nat m n" proof (induction m n rule: divmod_nat_tm.induct) case (1 m n) show ?case proof (cases "n = 0 ∨ m < n") case True thenshow ?thesis unfolding divmod_nat_tm.simps[of m n] by (simp add: Euclidean_Rings.divmod_nat_if) next case False thenhave"val (divmod_nat_tm m n) = (let (q, r) = val (divmod_nat_tm (m - n) n) in (Suc q, r))" unfolding divmod_nat_tm.simps[of m n] by (simp add: Let_def split: prod.splits) alsohave"... = (let (q, r) = Euclidean_Rings.divmod_nat (m - n) n in (Suc q, r))" using1 False by simp alsohave"... = Euclidean_Rings.divmod_nat m n" unfolding Euclidean_Rings.divmod_nat_if[of m n] by (simp add: False split: prod.splits) finallyshow ?thesis . qed qed
lemma time_divmod_nat_tm_aux: assumes"r < n" assumes"n > 0" shows"time (divmod_nat_tm (n * k + r) n) = 5 * k + 3 * n * k + time (divmod_nat_tm r n)" using assms proof (induction k) case0 thenshow ?caseby simp next case (Suc k) thenshow ?case unfolding divmod_nat_tm.simps[of "n * (Suc k) + r" n] by (simp add: time_equal_nat_tm time_less_nat_tm split: prod.splits) qed
lemma time_divmod_nat_tm_le: "time (divmod_nat_tm m n) ≤ 8 * m + 2 * n + 5" proof (cases "n = 0 ∨ m < n") case True have"time (divmod_nat_tm m n) = time (equal_nat_tm n 0) + time (less_nat_tm m n) + 2" unfolding divmod_nat_tm.simps[of m n] by (simp add: True) alsohave"... ≤ 2 * min m n + 5" apply (subst time_equal_nat_tm) apply (estimation estimate: time_less_nat_tm_le) by simp finallyshow ?thesis by simp next case False
define k r where"k = m div n""r = m mod n" thenhave krn: "m = n * k + r"by simp from k_r_def have"r < n"using False by simp have"time (divmod_nat_tm m n) = 5 * k + 3 * n * k + time (divmod_nat_tm r n)" apply (subst krn, intro time_divmod_nat_tm_aux, intro ‹r < n›) using False by simp alsohave"time (divmod_nat_tm r n) = time (equal_nat_tm n 0) + time (less_nat_tm r n) + 2" unfolding divmod_nat_tm.simps[of r n] by (simp add: ‹r < n›) alsohave"... ≤ 2 * min r n + 5" apply (subst time_equal_nat_tm) apply (estimation estimate: time_less_nat_tm_le) by simp finallyhave"time (divmod_nat_tm m n) ≤ 5 * k + 3 * n * k + 2 * n + 5" by simp alsohave"... ≤ 5 * k + 3 * m + 2 * n + 5" using k_r_def by simp alsohave"... ≤ 8 * m + 2 * n + 5" using k_r_def by simp finallyshow ?thesis . qed
definition divide_nat_tm :: "nat ==> nat ==> nat tm"where "divide_nat_tm m n =1 divmod_nat_tm m n 🍋 fst_tm"
lemma val_divide_nat_tm[simp, val_simp]: "val (divide_nat_tm m n) = m div n" by (simp add: divide_nat_tm_def Euclidean_Rings.divmod_nat_def)
lemma time_divide_nat_tm_le: "time (divide_nat_tm m n) ≤ 8 * m + 2 * n + 7" using time_divmod_nat_tm_le[of m n] by (simp add: divide_nat_tm_def)
definition mod_nat_tm :: "nat ==> nat ==> nat tm"where "mod_nat_tm m n =1 divmod_nat_tm m n 🍋 snd_tm"
lemma val_mod_nat_tm[simp, val_simp]: "val (mod_nat_tm m n) = m mod n" by (simp add: mod_nat_tm_def Euclidean_Rings.divmod_nat_def)
lemma time_mod_nat_tm_le: "time (mod_nat_tm m n) ≤ 8 * m + 2 * n + 7" using time_divmod_nat_tm_le[of m n] by (simp add: mod_nat_tm_def)
definition dvd_tm where"dvd_tm a b =1 do { b_mod_a ← mod_nat_tm b a; equal_nat_tm b_mod_a 0 }"
subsubsection"@{const dvd}"
lemma val_dvd_tm[simp, val_simp]: "val (dvd_tm a b) = (a dvd b)" unfolding dvd_tm_def dvd_eq_mod_eq_0 by simp
lemma time_dvd_tm_le: "time (dvd_tm a b) ≤ 8 * b + 2 * a + 9" unfolding dvd_tm_def tm_time_simps val_mod_nat_tm time_equal_nat_tm using time_mod_nat_tm_le[of b a] by simp
subsubsection"@{const even} / @{const odd}"
definition even_tm where"even_tm a = dvd_tm 2 a"
lemma val_even_tm[simp, val_simp]: "val (even_tm a) = even a" unfolding even_tm_def by simp
lemma time_even_tm_le: "time (even_tm a) ≤ 8 * a + 13" unfolding even_tm_def tm_time_simps using time_dvd_tm_le[of 2 a] by simp
definition odd_tm where"odd_tm a = dvd_tm 2 a 🍋 Not_tm"
lemma val_odd_tm[simp, val_simp]: "val (odd_tm a) = odd a" unfolding odd_tm_def by simp
lemma time_odd_tm_le: "time (odd_tm a) ≤ 8 * a + 14" unfolding odd_tm_def tm_time_simps using time_dvd_tm_le[of 2 a] by simp
subsection"List functions"
subsubsection"@{const take}"
fun take_tm :: "nat ==> 'a list ==> 'a list tm"where "take_tm n [] =1 return []"
| "take_tm n (x # xs) =1 (case n of 0 ==> return [] | Suc m ==> do { r ← take_tm m xs; return (x # r) })"
lemma val_take_tm[simp, val_simp]: "val (take_tm n xs) = take n xs" by (induction n xs rule: take_tm.induct) (simp_all split: nat.splits)
lemma time_take_tm: "time (take_tm n xs) = min n (length xs) + 1" by (induction n xs rule: take_tm.induct) (simp_all split: nat.splits)
lemma time_take_tm_le: "time (take_tm n xs) ≤ n + 1" by (simp add: time_take_tm)
subsubsection"@{const drop}"
fun drop_tm :: "nat ==> 'a list ==> 'a list tm"where "drop_tm n [] =1 return []"
| "drop_tm n (x # xs) =1 (case n of 0 ==> return (x # xs) | Suc m ==> do { r ← drop_tm m xs; return r })"
lemma val_drop_tm[simp, val_simp]: "val (drop_tm n xs) = drop n xs" by (induction n xs rule: drop_tm.induct) (simp_all split: nat.splits)
lemma time_drop_tm: "time (drop_tm n xs) = min n (length xs) + 1" by (induction n xs rule: drop_tm.induct) (simp_all split: nat.splits)
lemma time_drop_tm_le: "time (drop_tm n xs) ≤ n + 1" by (simp add: time_drop_tm)
subsubsection"@{const append}"
fun append_tm :: "'a list ==> 'a list ==> 'a list tm"where "append_tm [] ys =1 return ys"
| "append_tm (x # xs) ys =1 do { r ← append_tm xs ys; return (x # r) }"
lemma time_rev_tm_le[simp]: "time (rev_tm xs) = length xs + 2" unfolding rev_tm_def using time_fold_tm_Cons by auto
subsubsection"@{const replicate}"
fun replicate_tm :: "nat ==> 'a ==> 'a list tm"where "replicate_tm 0 x =1 return []"
| "replicate_tm (Suc n) x =1 do { r ← replicate_tm n x; return (x # r) }"
lemma val_replicate_tm[simp, val_simp]: "val (replicate_tm n x) = replicate n x" by (induction n x rule: replicate_tm.induct) simp_all
lemma time_replicate_tm: "time (replicate_tm n x) = n + 1" by (induction n x rule: replicate_tm.induct) simp_all
subsubsection"@{const length}"
fun gen_length_tm :: "nat ==> 'a list ==> nat tm"where "gen_length_tm n [] =1 return n"
| "gen_length_tm n (x # xs) =1 gen_length_tm (Suc n) xs"
lemma val_gen_length_tm[simp, val_simp]: "val (gen_length_tm n xs) = List.length_tailrec xs n" by (induction n xs rule: gen_length_tm.induct) simp_all
lemma time_gen_length_tm[simp]: "time (gen_length_tm n xs) = length xs + 1" by (induction n xs rule: gen_length_tm.induct) simp_all
fun butlast_tm :: "'a list ==> 'a list tm"where "butlast_tm [] =1 return []"
| "butlast_tm (x # xs) =1 do { b ← null_tm xs; if b then return [] else do { r ← butlast_tm xs; return (x # r) } }"
fun map_tm :: "('a ==> 'b tm) ==> 'a list ==> 'b list tm"where "map_tm f [] =1 return []"
| "map_tm f (x # xs) =1 do { r ← f x; rs ← map_tm f xs; return (r # rs) }"
lemma val_map_tm[simp, val_simp]: "val (map_tm f xs) = map (λx. val (f x)) xs" by (induction f xs rule: map_tm.induct) simp_all
lemma time_map_tm: "time (map_tm f xs) = (∑i ← xs. time (f i)) + length xs + 1" by (induction f xs rule: map_tm.induct) (simp_all)
lemma time_map_tm_constant: assumes"∧i. i ∈ set xs ==> time (f i) = c" shows"time (map_tm f xs) = (c + 1) * length xs + 1" proof - have"time (map_tm f xs) = (∑i ← xs. time (f i)) + length xs + 1" by (simp add: time_map_tm) alsohave"... = (∑i ← xs. c) + length xs + 1" using assms iffD2[OF map_eq_conv, of xs] by metis alsohave"... = c * length xs + length xs + 1" using sum_list_triv[of c xs] by simp finallyshow ?thesis by simp qed
lemma time_map_tm_bounded: assumes"∧i. i ∈ set xs ==> time (f i) ≤ c" shows"time (map_tm f xs) ≤ (c + 1) * length xs + 1" proof - have"time (map_tm f xs) = (∑i ← xs. time (f i)) + length xs + 1" by (simp add: time_map_tm) alsohave"... ≤ (∑i ← xs. c) + length xs + 1" by (intro add_mono order.refl sum_list_mono assms) argo alsohave"... = c * length xs + length xs + 1" using sum_list_triv[of c xs] by simp finallyshow ?thesis by simp qed
subsubsection"@{const foldl}"
fun foldl_tm :: "('a ==> 'b ==> 'a tm) ==> 'a ==> 'b list ==> 'a tm"where "foldl_tm f a [] =1 return a"
| "foldl_tm f a (x # xs) =1 do { r ← f a x; foldl_tm f r xs }"
lemma val_foldl_tm[simp, val_simp]: "val (foldl_tm f a xs) = foldl (λx y. val (f x y)) a xs" by (induction f a xs rule: foldl_tm.induct; simp)
subsubsection"@{const concat}"
fun concat_tm where "concat_tm [] =1 return []"
| "concat_tm (x # xs) =1 do { r ← concat_tm xs; append_tm x r }"
lemma val_nth_tm[simp, val_simp]: assumes"i < length xs" shows"val (nth_tm xs i) = xs ! i" using assms proof (induction i arbitrary: xs) case0 thenshow ?caseusing length_greater_0_conv[of xs] neq_Nil_conv[of xs] by auto next case (Suc i) thenobtain x xs' where xsr: "xs = x # xs'"by (meson Suc_lessE length_Suc_conv) thenhave"i < length xs'"using Suc.prems by simp from Suc.IH[OF this] show ?caseunfolding xsr by simp qed
lemma time_nth_tm[simp]: assumes"i < length xs" shows"time (nth_tm xs i) = i + 1" using assms proof (induction i arbitrary: xs) case0 thenshow ?caseusing length_greater_0_conv[of xs] neq_Nil_conv[of xs] by auto next case (Suc i) thenobtain x xs' where xsr: "xs = x # xs'"by (meson Suc_lessE length_Suc_conv) thenhave"i < length xs'"using Suc.prems by simp from Suc.IH[OF this] show ?caseunfolding xsr by simp qed
subsubsection"@{const zip}"
fun zip_tm :: "'a list ==> 'b list ==> ('a × 'b) list tm"where "zip_tm xs [] =1 return []"
| "zip_tm [] ys =1 return []"
| "zip_tm (x # xs) (y # ys) =1 do { rs ← zip_tm xs ys; return ((x, y) # rs) }"
lemma val_zip_tm[simp, val_simp]: "val (zip_tm xs ys) = zip xs ys" by (induction xs ys rule: zip_tm.induct; simp)
definition map2_tm where "map2_tm f xs ys =1 do { xys ← zip_tm xs ys; map_tm (λ(x,y). f x y) xys }"
lemma val_map2_tm[simp, val_simp]: "val (map2_tm f xs ys) = map2 (λx y. val (f x y)) xs ys" unfolding map2_tm_def by (simp split: prod.splits)
lemma time_map2_tm_bounded: assumes"length xs = length ys" assumes"∧x y. x ∈ set xs ==> y ∈ set ys ==> time (f x y) ≤ c" shows"time (map2_tm f xs ys) ≤ (c + 2) * length xs + 3" proof - have"time (map2_tm f xs ys) = length xs + 2 + time (map_tm (λ(x, y). f x y) (zip xs ys))" unfolding map2_tm_def by (simp add: assms) alsohave"... ≤ length xs + 2 + ((c + 1) * length (zip xs ys) + 1)" apply (intro add_mono order.refl time_map_tm_bounded) using assms by (auto split: prod.splits elim: in_set_zipE) alsohave"... = (c + 2) * length xs + 3" using assms by simp finallyshow ?thesis . qed
subsubsection"@{const upt}"
function upt_tm where "upt_tm i j =1 do { b ← less_nat_tm i j; (if b then do { rs ← upt_tm (Suc i) j; return (i # rs) } else return [] ) }" by pat_completeness auto terminationby (relation "Wellfounded.measure (λ(i, j). j - i)") simp_all declare upt_tm.simps[simp del]
lemma val_upt_tm[simp, val_simp]: "val (upt_tm i j) = [i..<j]" apply (induction i j rule: upt_tm.induct)
subgoal for i j by (cases "i < j"; simp add: upt_tm.simps[of i j] upt_conv_Cons) done lemma time_upt_tm_le: "time (upt_tm i j) ≤ (j - i) * (2 * j + 3) + 2 * j + 2" proof (induction i j rule: upt_tm.induct) case (1 i j) thenshow ?case proof (cases "i < j") case True thenhave"time (upt_tm i j) = (2 * i + 3) + time (upt_tm (Suc i) j)" unfolding upt_tm.simps[of i j] tm_time_simps by (simp add: time_less_nat_tm) alsohave"... ≤ (2 * j + 3) + ((j - Suc i) * (2 * j + 3) + 2 * j + 2)" apply (intro add_mono mult_le_mono order.refl)
subgoal using True by simp
subgoal using1 True by simp done alsohave"... = (j - Suc i + 1) * (2 * j + 3) + 2 * j + 2" by simp alsohave"j - Suc i + 1 = (j - i)" using True by simp finallyshow ?thesis . next case False thenshow ?thesis by (simp add: upt_tm.simps[of i j] time_less_nat_tm) qed qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.