(*<*) theory Lecture1 imports Main LaTeXsugar OptionalSugar begin (*>*) text{* A \textbf{lemma} introduces a proposition followed by a proof. Isabelle has several automatic procedures for generating proofs, one of which is called \textit{simp}, short for simplification. The \textit{simp} procedure applies a set of rewrite rules that is initially seeded with a large number of rules concerning the built-in objects. *} lemma most_trivial: "True" by blast section "Isabelle's functional language" text{* This section introduces the functional language that is embedded in Isabelle. The functional language is closely related to Standard ML. *} subsection "Natural numbers, integers, and booleans" text{* Isabelle provides Peano-style natural numbers. There are two constructors for natural numbers: '0' and 'Suc n' (where 'n' is a previously constructed natural number). Numerals such as '1' are shorthand for the appropriate Peano numeral, in this case 'Suc 0'. *} lemma "Suc 0 = 1" by simp text{* Isabelle also provides the usual arithmetic operations on naturals, such as '+' and '*'. The double-colon notation ascribes a type to a term. *} lemma "1 + 2 = (3::nat)" by simp lemma "1 + 2 = (3::nat)" by simp lemma "2 * 3 = (6::nat)" by simp text{* Isabelle provides a division function for naturals, called div, that takes the \textit{floor} of the result (this ensures that the result is a natural number and not a real number). *} lemma "3 div 2 = (1::nat)" by simp text{* The mod function gives the remainder. *} lemma "3 mod 2 = (1::nat)" by simp text{* Isabelle also provide integers. *} lemma "1 + -2 = (-1::int)" by simp text{* Confusingly, the numerals, such as '1', are overloaded and can be either naturals or integers, depending on the context. It is sometimes necessary to use type ascription to tell Isabelle which you want. *} text{* The following are examples of Boolean expressions. *} lemma "True \ True = True" by simp lemma "True \ False = False" by simp lemma "True \ False = True" by simp lemma "False \ False = False" by simp lemma "\ True = (False::bool)" by simp lemma "False \ True" by simp lemma "\ x. x = x" by simp lemma "\ x. x = 1" by simp subsection "Definitions (non-recursive)" constdefs xor :: "bool \ bool \ bool" "xor A B \ (A \ \ B) \ (\ A \ B)" lemma "xor True True = False" by (simp add: xor_def) text{* Add the xor definition to the default set of simplification rules. *} declare xor_def[simp] subsection "Let expressions" text{* A 'let' expression gives a name to value. The name can be used anywhere after the 'in', i.e., anywhere in the body of the 'let'. *} lemma "(let x = 3 in x * x) = (9::nat)" by simp subsection "Pairs" text{* Pairs are created with parentheses and commas. The 'fst' function retrieves the first element of the pair and 'snd' retrieves the second. *} lemma "let p = (2,3)::nat \ nat in fst p + 1 = snd p" by simp subsection "Lists" text{* A list can be created using a comma separated sequence of items (all of the same type) enclosed in square brackets. The empty list is written @{term "[]"}. The @{text "#"} operator adds an element to the front of a list (aka 'cons'). *} lemma "let l = [1,2,3]::(nat list) in hd l = 1 \ tl l = [2,3]" by simp lemma "1#(2#(3#[])) = [1,2,3]" by simp lemma "length [1,2,3] = 3" by simp text{* Section 38 of ``HOL: The basis of Higher-Order Logic'' documents many useful functions on lists and lemmas concerning properties of these functions. *} subsection "Records" text{* A record is a collection of named values, similar to structs in C and records in Pascal. The following is an example declaration of a point record. *} record point = x_coord :: int y_coord :: int text{* The following shows the creation of a record and accessing a field of the record. The Isabelle notation is somewhat unusual because the typical dot notation for field access is not used, and instead the field name is treated as a function. Some care must be taken when choosing field names because they become globally visible, and will conflict with any other uses of the names. So, for example, it would be bad to use x and y for the field names of the point record. *} constdefs pt :: point "pt \ \x_coord = 3, y_coord = 7\" lemma "x_coord pt = 3" by (simp add: pt_def) text{* The record update notation, shown below, creates a copy of a record except for the indicated value. *} lemma "x_coord (pt\x_coord:=4\) = 4" by (simp add: pt_def) subsection "Lambdas (anonymous functions)" lemma "(\ x. x + x) 1 = (2::nat)" by simp subsection "Conditionals: if and case" lemma "(if True then 1 else 2) = 1" by simp lemma "(case 1 of 0 \ False | Suc m \ True)" by simp subsection "Datatypes and primitive recursion" datatype 'a List = Nily | Consy 'a "'a List" consts app :: "'a List \ 'a List \ 'a List" primrec "app Nily ys = ys" "app (Consy x xs) ys = Consy x (app xs ys)" text{* Note that one of the arguments in the recursive call must be a part of one of the parameters. *} lemma "app (Consy 1 (Consy 2 Nily)) (Consy 3 Nily) = (Consy 1 (Consy 2 (Consy 3 Nily)))" by simp subsubsection "Exercises" text{* Define a function that sums the first n natural numbers. *} (*<*) end (*>*) (* LocalWords: LaTeXsugar OptionalSugar Isabelle simp textbf textit Peano Suc *) (* LocalWords: Isabelle's fst snd nat aka hd tl HOL structs coord int pt ëx *) (* LocalWords: constdefs def xor bool Datatypes datatype Nily Consy consts ys *) (* LocalWords: app primrec xs Isar Isar's qed congI notag conjI thm vars conj *) (* LocalWords: IfThen noindent qp emph impI qquad za ab aa bb arith ponens mp *) (* LocalWords: disjI ac bc disjE Equational datatypes lhs rhs cdots sumto div *) (* LocalWords: eq nn distr amc bmc IH tn mult distrib assoc zs Velleman *)