section \<open>Demo Theory of Session 12\<close> theory Demo12 imports Main (* "HOL-Library.Code_Target_Numeral" *) begin subsection \<open>Document Generation\<close> text \<open> This theory (importing @{theory Main}) has two purposes: \<^enum> it constitutes, together with the corresponding @{file ROOT} file, an example of an Isabelle session, and \<^enum> illustrates the usage of document \<open>antiquotations\<close> In order to produce a PDF run @{verbatim "isabelle build -v -D ."} in the session directory @{dir "."}. With plain text like this `@{text "Cons x xs"}' we can typeset arbitrary terms in Isabelle inner syntax. If you want to have Isar keywords treated in a special way use @{verbatim \<open>@{theory_text "..."}\<close>} instead. Consider, for example: \begin{center} @{theory_text "datatype term but also other words"} \end{center} \<close> subsection \<open>Document Antiquotations\<close> text \<open> With \<^emph>\<open>document antiquotations\<close> we can achieve many things. We can typeset: \<^item> terms (like @{term "[1,2,3,4]::nat list"}) \<^item> constants (like @{const Cons}) \<^item> types (like @{typeof "Cons"} and @{typ "nat set"}) \<^item> type constructors (like @{type "list"}) \<^item> theorems (like @{thm HOL.refl} and @{lemma "1 = 1" by (rule refl)}) \<^item> ... \<^item> There are several more antiquotations than those which are described here or in the slides. See a list via @{command print_antiquotations}. There are usually two version to type antiquotation, e.g., obviously \<^term>\<open>(True, x)\<close> and @{term "(True, x)"} are identical. \<close> lemma app_assoc: "xs @ (ys @ zs) = (xs @ ys) @ zs" by simp text \<open> We just proved associativity of @{const append} in @{command lemma} @{thm [source] app_assoc}. The exact statement of this property is: @{thm app_assoc}. By the way, did you know that the Isabelle knows the factorial function? The value of @{term "fact 5 :: int"} is @{value "fact 5 :: int"}.\<close> subsection \<open>Type Classes\<close> text \<open> See also @{doc classes}. \<close> subsubsection \<open>Transforming Arbitrary Values to Strings\<close> class Show = fixes "show" :: "'a \<Rightarrow> string" declare [[show_sorts]] term "show" declare [[show_sorts=false]] term "show" text \<open> Characters are an instance of the @{class Show} class, that is, they can be transformed into @{typ string}s \<close> instantiation char :: Show begin definition show_char :: "char \<Rightarrow> string" where "show_char c = [c]" instance .. end text \<open> Pairs are an instance of the @{class Show} class. \<close> instantiation prod :: (Show, Show) Show begin fun show_prod :: "('a \<times> 'b) \<Rightarrow> string" where "show_prod (x, y) = CHR ''('' # show x @ CHR '','' # show y @ [CHR '')'']" instance .. end value "show (CHR ''c'', CHR ''d'')" text \<open> Lists are an instance of @{class Show}. \<close> instantiation list :: (Show) Show begin fun show_list :: "'a list \<Rightarrow> string" where "show_list Nil = []" | "show_list (x#xs) = show x @ show_list xs" instance .. end value "show ''foo bar?''" subsubsection \<open>Total Orders\<close> class partial_order = fixes LEQ :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infix "\<^bold>\<le>" 50) assumes refl: "x \<^bold>\<le> x" and antisym: "x \<^bold>\<le> y \<Longrightarrow> y \<^bold>\<le> x \<Longrightarrow> x = y" and trans: "x \<^bold>\<le> y \<Longrightarrow> y \<^bold>\<le> z \<Longrightarrow> x \<^bold>\<le> z" begin definition LT :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infix "\<^bold><" 50) where "x \<^bold>< y \<longleftrightarrow> x \<^bold>\<le> y \<and> x \<noteq> y" end thm antisym class total_order = partial_order + assumes total: "x \<^bold>< y \<or> y \<^bold>< x \<or> x = y" begin (* we can reason abstractly within the class *) lemma not_eq_imp_lt: "x \<noteq> y \<Longrightarrow> x \<^bold>< y \<or> y \<^bold>< x " using total[of x y] by auto end (* or outside the class *) lemma less_lt_trans: "x \<^bold>\<le> y \<Longrightarrow> y \<^bold>< z \<Longrightarrow> x \<^bold>< (z :: 'a :: total_order)" by (metis LT_def partial_order_class.antisym partial_order_class.trans) instantiation nat :: partial_order begin fun LEQ_nat :: "nat \<Rightarrow> nat \<Rightarrow> bool" where "0 \<^bold>\<le> (y::nat) \<longleftrightarrow> True" | "Suc x \<^bold>\<le> Suc y \<longleftrightarrow> x \<^bold>\<le> y" | "x \<^bold>\<le> (y::nat) \<longleftrightarrow> False" lemma LEQ_nat_def: fixes x y :: nat shows "x \<^bold>\<le> y \<longleftrightarrow> (\<exists>n. y = x + n)" by (induction x y rule: LEQ_nat.induct) auto instance by (standard) (auto simp: LEQ_nat_def) end lemma LEQ_nat_total: fixes x y :: nat shows "x \<^bold>\<le> y \<or> y \<^bold>\<le> x" proof (induction x arbitrary: y) case (Suc x y) then show ?case by (cases y) auto qed simp instance nat :: total_order proof fix x y :: nat show "x \<^bold>< y \<or> y \<^bold>< x \<or> x = y" using LEQ_nat_total [of x y] unfolding LT_def by blast qed subsubsection \<open>Locales\<close> locale vector_space = fixes scale :: "'a :: field \<Rightarrow> 'v :: ab_group_add \<Rightarrow> 'v" assumes scale_scale: "scale x (scale y v) = scale (x * y) v" and scale_one: "scale 1 v = v" and scale_add_right: "scale x (v + w) = scale x v + scale x w" and scale_add_left: "scale (x + y) v = scale x v + scale y v" context vector_space begin (* reason about abstract vector-spaces *) lemma scale_0[simp]: "scale 0 v = 0" by (metis add.right_neutral add_left_cancel scale_add_left) (* add definitions for arbitrary vector-space *) fun linear_combination :: "('a \<times> 'v)list \<Rightarrow> 'v" where "linear_combination [] = 0" | "linear_combination ((x,v) # list) = scale x v + linear_combination list" lemma lincomb_0: "(\<And> x v. (x,v) \<in> set list \<Longrightarrow> x = 0) \<Longrightarrow> linear_combination list = 0" by (induct list; force) end interpretation field_vs: vector_space "(*)" (* choose 'v = 'a *) apply (unfold_locales) apply (auto simp: field_simps) done (* we could define arbitrary further instances of vector_spaces *) thm field_vs.scale_0 term field_vs.linear_combination thm field_vs.lincomb_0 thm vector_space.scale_0 term vector_space.linear_combination thm vector_space.lincomb_0 end