(* Title: The Chop Operation on Lambda-Free Higher-Order Terms Author:AlexanderBentkamp<a.bentkampatvu.nl>,2018 Maintainer:AlexanderBentkamp<a.bentkampatvu.nl>
*)
section‹The Chop Operation on Lambda-Free Higher-Order Terms›
theory Chop imports Embeddings begin
definition chop :: "('s, 'v) tm ==> ('s, 'v) tm"where "chop t = apps (hd (args t)) (tl (args t))"
subsection‹Basic properties›
lemma chop_App_Hd: "is_Hd s ==> chop (App s t) = t" unfolding chop_def args.simps using args_Nil_iff_is_Hd by force
lemma chop_apps: "is_App t ==> chop (apps t ts) = apps (chop t) ts" unfolding chop_def by (simp add: args_Nil_iff_is_Hd)
lemma vars_chop: "is_App t ==> vars (chop t) ∪ vars_hd (head t) = vars t" by (induct rule:tm_induct_apps; metis (no_types, lifting) chop_def UN_insert Un_commute list.exhaust_sel list.simps(15)
args_Nil_iff_is_Hd tm.simps(17) tm_exhaust_apps_sel vars_apps)
lemma ground_chop: "is_App t ==> ground t ==> ground (chop t)" using vars_chop by auto
lemma hsize_chop_lt: "is_App t ==> hsize (chop t) < hsize t" by (simp add: Suc_le_lessD less_or_eq_imp_le hsize_chop)
lemma chop_fun: assumes"is_App t""is_App (fun t)" shows"App (chop (fun t)) (arg t) = chop t" proof - have"args (fun t) ≠ []" using assms(2) args_Nil_iff_is_Hd by blast thenshow ?thesis unfolding chop_def using assms(1) by (metis (no_types) App_apps args.simps(2) hd_append2 tl_append2 tm.collapse(2)) qed
subsection‹Chop and the Embedding Relation›
lemma emb_step_chop: "is_App t ==> t →emb chop t" proof (induct "num_args t - 1" arbitrary:t) case0 have nil: "num_args t = 0 ==> t →emb chop t"unfolding chop_def using0 args_Nil_iff_is_Hd by force have single: "∧a. args t = [a] ==> t →emb chop t"unfolding chop_def by (metis "0.prems" apps.simps(1) args.elims args_Nil_iff_is_Hd emb_step_arg last.simps last_snoc list.sel(1) list.sel(3) tm.sel(6)) thenshow ?caseusing nil single by (metis "0.hyps" length_0_conv length_tl list.exhaust_sel) next case (Suc x) have1:"apps (Hd (head t)) (butlast (args t)) →emb chop (apps (Hd (head t)) (butlast (args t)))" using Suc(1)[of "apps (Hd (head t)) (butlast (args t))"] by (metis Suc.hyps(2) Suc_eq_plus1 add_diff_cancel_right' args_Nil_iff_is_Hd length_butlast list.size(3) nat.distinct(1) tm_exhaust_apps_sel tm_inject_apps) have2:"App (apps (Hd (head t)) (butlast (args t))) (last (args t)) = t" by (simp add: App_apps Suc.prems args_Nil_iff_is_Hd) have3:"App (chop (apps (Hd (head t)) (butlast (args t)))) (last (args t)) = chop t" proof - have f1: "hd (args t) = hd (butlast (args t))" by (metis Suc.hyps(2) Suc.prems append_butlast_last_id args_Nil_iff_is_Hd hd_append2 length_0_conv length_butlast nat.simps(3)) have"tl (args t) = tl (butlast (args t)) @ [last (args t)]" by (metis (no_types) Suc.hyps(2) Suc.prems append_butlast_last_id args_Nil_iff_is_Hd length_0_conv length_butlast nat.simps(3) tl_append2) thenshow ?thesis using f1 chop_def by (metis App_apps append_Nil args.simps(1) args_apps) qed thenshow ?caseusing123by (metis context_left) qed
lemma chop_emb_step_at: assumes"is_App t" shows"chop t = emb_step_at (replicate (num_args (fun t)) Left) Right t" using assms proof (induct "num_args (fun t)" arbitrary: t) case0 thenhave rep_Nil:"replicate (num_args (fun t)) dir.Left = []" by simp thenshow ?caseunfolding rep_Nil by (metis "0.hyps""0.prems" emb_step_at_right append_Nil apps.simps(1) args.simps(2) chop_def length_0_conv list.sel(1) list.sel(3) tm.collapse(2)) next case (Suc n) thenshow ?caseusing Suc.hyps(1)[of "fun t"] using emb_step_at_left_context args.elims args_Nil_iff_is_Hd chop_fun butlast_snoc diff_Suc_1 length_0_conv length_butlast nat.distinct(1) replicate_Suc tm.collapse(2) tm.sel(4) by metis qed
lemma emb_step_at_chop: assumes emb_step_at: "emb_step_at p Right t = s" and pos:"position_of t (p @ [Right])" and all_Left: "list_all (λx. x = Left) p" shows"chop t = s ∨ chop t →emb s" proof - have"is_App t" by (metis emb_step_at_if_position emb_step_at_is_App emb_step_equiv pos) have p_replicate: "replicate (length p) Left = p"using replicate_length_same[of p Left] by (simp add: Ball_set all_Left) show ?thesis proof (cases "Suc (length p) = num_args t") case True thenhave"p = replicate (num_args (fun t)) Left"using p_replicate by (metis Suc_inject ‹is_App t› args.elims args_Nil_iff_is_Hd length_append_singleton tm.sel(4)) thenhave"chop t = s"unfolding chop_emb_step_at[OF ‹is_App t›] using pos emb_step_at by blast thenshow ?thesis by blast next case False thenhave"Suc (length p) < num_args t" using pos emb_step_at ‹is_App t›‹list_all (λx. x = dir.Left) p› proof (induct p arbitrary:t s) case Nil thenshow ?case by (metis Suc_lessI args_Nil_iff_is_Hd length_greater_0_conv list.size(3)) next case (Cons a p) have"a = Left" using Cons.prems(5) by auto have1:"Suc (length p) ≠ num_args (fun t)" by (metis (no_types, lifting) Cons.prems(1) Cons.prems(4) args.elims args_Nil_iff_is_Hd length_Cons length_append_singleton tm.sel(4)) have2:"position_of (fun t) (p @ [Right])" using‹position_of t ((a # p) @ [Right])›‹is_App t›
Cons.prems(5) by (simp add: list_all_iff flip: position_of_left [of ‹fun t›‹arg t›]) have3: "emb_step_at p dir.Right (fun t) = emb_step_at p dir.Right (fun t)" using emb_step_at_left_context[of p Right "fun t""arg t"] by blast have‹is_App (fun t)› by (metis "2" Embeddings.emb_step_at_head emb_step_at_if_position emb_step_equiv
tm.collapse(1)) from123‹is_App (fun t)›have"Suc (length p) < num_args (fun t)" apply (rule Cons.hyps) using Cons.prems(5) apply (simp add: list_all_iff) done thenshow ?case by (metis Cons.prems(4) Suc_less_eq2 args.simps(2) length_Cons length_append_singleton tm.collapse(2)) qed
define q where"q = replicate (num_args (fun t) - Suc (length p)) dir.Left" have"chop t = emb_step_at (p @ [Left] @ q) dir.Right t" proof - have"length p + (num_args (fun t) - length p) = num_args (fun t)" using‹Suc (length p) < num_args t› by (metis Suc_less_eq2 ‹is_App t› args.simps(2) diff_Suc_1 leD length_butlast nat_le_linear
ordered_cancel_comm_monoid_diff_class.add_diff_inverse snoc_eq_iff_butlast tm.collapse(2)) thenhave1:"replicate (num_args (fun t)) dir.Left = p @ replicate (num_args (fun t) - length p) dir.Left" by (metis p_replicate replicate_add) have"0 < num_args (fun t) - length p" by (metis (no_types) False ‹is_App t›‹length p + (num_args (fun t) - length p) = num_args (fun t)› args.simps(2) length_append_singleton less_Suc_eq less_add_Suc1 tm.collapse(2) zero_less_diff) thenhave"replicate (num_args (fun t) - length p) dir.Left = [Left] @ q"unfoldingq_def by (metis (no_types) Cons_replicate_eq Nat.diff_cancel Suc_eq_plus1 ‹length p + (num_args (fun t) - length p) = num_args (fun t)› append_Cons self_append_conv2) thenshow ?thesis using chop_emb_step_at using‹is_App t›1 by (simp add: chop_emb_step_at) qed thenhave"chop t →emb s" using pos merge_emb_step_at[of p Right q Right t] by (metis emb_step_at_if_position opp_simps(1) emb_step_at pos_emb_step_at_opp) thenshow ?thesis by blast qed qed
lemma emb_step_at_remove_arg: assumes emb_step_at: "emb_step_at p Left t = s" and pos:"position_of t (p @ [Left])" and all_Left: "list_all (λx. x = Left) p" shows"let i = num_args t - Suc (length p) in head t = head s ∧ i < num_args t ∧ args s = take i (args t) @ drop (Suc i) (args t)" proof - have"is_App t" by (metis emb_step_at_if_position emb_step_at_is_App emb_step_equiv pos) have C1: "head t = head s" using all_Left emb_step_at pos proof (induct p arbitrary:s t) case Nil thenhave"s = emb_step_at [] dir.Left (App (fun t) (arg t))" by (metis position_of.elims(2) snoc_eq_iff_butlast tm.collapse(2) tm.discI(2)) thenhave"s = fun t"by simp thenshow ?caseby simp next case (Cons a p) thenhave"a = Left"by simp thenhave"head (emb_step_at p Left (fun t)) = head t" by (metis Cons.hyps Cons.prems(1) head_fun list.pred_inject(2) position_if_emb_step_at) thenshow ?caseusing emb_step_at_left_context[of p a "fun t""arg t"] by (metis Cons.prems(2) ‹a = Left› emb_step_at_is_App head_App tm.collapse(2)) qed
let ?i = "num_args t - Suc (length p)"
have C2:"?i < num_args t" by (simp add: ‹is_App t› args_Nil_iff_is_Hd)
have C3:"args s = take ?i (args t) @ drop (Suc ?i) (args t)" using all_Left pos emb_step_at ‹is_App t›proof (induct p arbitrary:s t) case Nil thenshow ?caseusing emb_step_at_left[of "fun t""arg t"] by (simp, metis One_nat_def args.simps(2) butlast_conv_take butlast_snoc tm.collapse(2)) next case (Cons a p) have *: "position_of (fun t) (p @ [Left])" by (metis (full_types) Cons.prems(1) Cons.prems(2) Cons.prems(4) position_of_left
append_Cons list.pred_inject(2) tm.collapse(2)) have0:"args (emb_step_at p Left (fun t)) = take (num_args (fun t) - Suc (length p)) (args (fun t)) @ drop (Suc (num_args (fun t) - Suc (length p))) (args (fun t))" apply (rule Cons.hyps [of "fun t"]) using * Cons.prems apply (simp_all add: list_all_iff) apply (metis emb_step_at_if_position emb_step_at_is_App emb_step_equiv') done have1:"s = App (emb_step_at p Left (fun t)) (arg t)"using emb_step_at_left_context[of p Left "fun t""arg t"] using Cons.prems by auto
define k where k_def:"k = (num_args (fun t) - Suc (length p))" have2:"take k (args (fun t)) = take (num_args t - Suc (length (a # p))) (args t)" by (metis (no_types, lifting) Cons.prems(4) args.elims args_Nil_iff_is_Hd butlast_snoc
diff_Suc_eq_diff_pred diff_less k_def length_Cons length_butlast length_greater_0_conv
take_butlast tm.sel(4) zero_less_Suc) have k_def': "k = num_args t - Suc (Suc (length p))"using k_def by (metis args.simps(2) diff_Suc_Suc length_append_singleton local.Cons(5) tm.collapse(2)) have3:"args (fun t) @ [arg t] = args t" by (metis Cons.prems(4) args.simps(2) tm.collapse(2)) have"num_args t > 1"using‹position_of t ((a # p) @ [Left])› by (metis "3"‹position_of (fun t) (p @ [dir.Left])› args_Nil_iff_is_Hd butlast_snoc emb_step.simps emb_step_at_if_position length_butlast length_greater_0_conv tm.discI(2) zero_less_diff) thenhave"Suc k<num_args t"unfolding k_def' using‹1 < num_args t›by linarith have"∀k< num_args t. drop k (args (fun t)) @ [arg t] = drop k (args t)" by (metis (no_types, lifting) ‹args (fun t) @ [arg t] = args t› drop_butlast drop_eq_Nil last_drop leD snoc_eq_iff_butlast) thenshow ?caseusing0123 k_def' using‹Suc k < num_args t› k_def by auto qed show ?thesis using C1 C2 C3 by simp qed
lemma emb_step_cases [consumes 1, case_names chop extended_chop remove_arg under_arg]: assumes emb:"t →emb s" and chop:"chop t = s ==> P" and extended_chop:"chop t →emb s ==> P" and remove_arg:"∧i. head t = head s ==> i<num_args t ==> args s = take i (args t) @ drop (Suc i) (args t) ==> P" and under_arg:"∧i. head t = head s ==> num_args t = num_args s ==> args t ! i →emb args s ! i ==> (∧j. j<num_args t ==> i ≠ j ==> args t ! j = args s ! j) ==> P" shows P proof - obtain p d where pd_def:"emb_step_at p d t = s""position_of t (p @ [d])" using emb emb_step_equiv' position_if_emb_step_at by metis have"is_App t" by (metis emb emb_step_at_is_App emb_step_equiv) show ?thesis proof (cases "list_all (λx. x = Left) p") case True show ?thesis proof (cases d) case Left thenshow P using emb_step_at_remove_arg by (metis True pd_def(1) pd_def(2) remove_arg) next case Right thenshow P using True chop emb_step_at_chop extended_chop pd_def(1) pd_def(2) by blast qed next case False have1:"num_args t = num_args s"using emb_step_under_args_num_args by (metis False pd_def(1)) have2:"head t = head s"using emb_step_under_args_head by (metis False pd_def(1)) show ?thesis using12 under_arg emb_step_under_args_emb_step by (metis False pd_def(1) pd_def(2)) 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.