theory LiveDemo01 imports Main begin section \Warning\ text \Interactive theorem proving can be addictive!\ section \Beginner's Warning\ text \This theory contains many more elements that have not been covered in the first lecture. Just ignore what you do not understand. The next line is something you should ignore.\ declare [[names_short]] text \You can find several manuals and tutorials in the "Documentation"-tab on the left. In particular "prog-prove" is an up-to-date introduction to Isabelle/HOL. You can also invoke the documentation from the command line, e.g., by invoking: isabelle doc (* list all documentations *) isabelle doc prog-prove (* invoke specific documentation *) \ section \Documentation and Comments\ text \This is some text that is used to document a theory. It is surrounded by cartouches \\\, which are entered via << and >>. Within these texts, one may refer to Isabelle terms, types and theorems, e.g., @{typ "bool option"}, @{term "\ x. P x \ Q x"}, @{thm conjI}. You can CTRL-hover/click to get more information on these parts. Document generation will be covered later in this course.\ (* comments are completely ignored and may span several lines and even other outer syntax elements, e.g. lemma "P \ P" the stated lemma above. *) section \Examples from the lecture\ subsection \Types\ datatype ('a,'b)tree = Leaf 'a | Node "('a,'b)tree" 'b "('a,'b)tree" type_synonym ('a)special_tree = "(nat \ 'a, 'a list)tree" datatype 'a list = Nil | Cons 'a "'a list" type_synonym string = "char list" text \Here an error occurs: - you see an error in the left- and right margin of this tab - navigate the cursor to the problematic line - open the "Output"-tab in the bottom to see the error message.\ (* datatype foo = Bar foo *) subsection \Terms\ text \@{command "term"} just takes a term as argument and then determines its type. the type is visible in the "Output"-tab\ term "map (\ x :: nat. x + 1) [1, 3]" value "map (\ x :: nat. x + 1) [1, 3]" text \in the previous term, we use the predefined @{typ "'a List.list"}-type and corresponding @{const map}-function, and these are different from @{typ "'a list"} that is defined above\ term "(x :: nat) + (y + z) = (x + y) + z \ x + y = y + x" text \CTRL-click on @{const All} to jump to definition\ term "All (\ x. P x y)" text \Observe the output of the previous line. Usually one directly enters universal quantification via \.\ term "\ x. P x y" subsection \Expressiveness of HOL\ text \well-foundedness of a binary relation can be expressed\ type_synonym 'a rel = "'a \ 'a \ bool" definition "well_founded (R :: 'a rel) = (\ (\ f :: nat \ 'a . \ n :: nat. R (f n) (f (n + 1))))" text \the transitive closure of a relation can be expressed\ definition "trans_cl (R :: 'a rel) a b = (\ (f :: nat \ 'a) (n :: nat). f 0 = a \ f n = b \ n \ 0 \ (\ i. i < n \ R (f i) (f (i + 1))))" lemma "well_founded (trans_cl R) = well_founded R" proof text \The proof-state is visible in the "Output"-tab, if "Proof state" is enabled\ oops (* oops aborts a proof attempt *) text \induction on natural numbers is sound\ lemma "\ P :: nat \ bool. P 0 \ (\ n. P n \ P (n + 1)) \ (\ n. P n)" using nat.induct by auto (* do not try to understand proof *) subsection \Function definitions\ term "\ x. x \ x \ ((f :: ('a \ bool)) y)" fun append :: "'a list \ 'a list \ 'a list" where "append Nil ys = ys" | "append (Cons x xs) ys = Cons x (append xs ys)" text \The syntax @{typ "'a :: {linorder,numeral} \ 'a"} is similar to Haskells type-constraints, e.g. @{text "(Ord a, Num a) => a -> a"}. Hence, the following definition of \partition\ is restricted to lists of elements that provide a linear order so that we can compare elements by @{term "(\)"}.\ fun partition :: "'a :: linorder \ 'a list \ 'a list \ 'a list" where "partition p Nil = (Nil, Nil)" | "partition p (Cons x xs) = (let part = partition p xs; low = fst part; high = snd part in if x \ p then (Cons x low, high) else (low, Cons x high))" text \The definition of \qsort\ is not accepted, since the internal termination prover cannot show termination without further help.\ fun qsort :: "'a :: linorder list \ 'a list" where "qsort Nil = Nil" | "qsort (Cons x xs) = (case partition x xs of (low, high) \ append (qsort low) (Cons x (qsort high)))" text \Predicates can be recursive functions, too\ fun is_sorted :: "'a :: linorder list \ bool" where "is_sorted (Cons x (Cons y ys)) = (x \ y \ is_sorted (Cons y ys))" | "is_sorted _ = True" text \Note that @{term qsort} is still in blue-color, so a free variable. By contrast @{term is_sorted} is a (black) constant. Here a counter-example to the lemma is immediately detected. (there is a hint marked in blue on the left, where details are visible in the output-tab.)\ lemma "is_sorted (qsort xs)" oops ML \ val _ = Thm.implies_elim val _ = aconv val _ = Abs \ end (* of theory *)