···33\parent{isa-001B}
44\import{shiki-macros}
55\put\shiki/language{Isabelle Theory}
66-\title{The \code{two} type}
77-\shiki{datatype two = ONE | TWO
66+\title{The \code{oot} type}
77+\shiki{datatype oot = ONE | TWO
88print_theorems
99}
1010-\p{This defines a type called \code{two} with two values, \code{ONE : two} and \code{TWO : two}. The \code{print_theorems} command here allows us to see all of the theorems automatically created by the \code{datatype} command, chiefly that the constants \code{ONE} and \code{TWO} are \em{disjoint} (i.e. \code{ONE ≠ TWO}) and \em{exhaustive} (i.e. that there are no other values of type \code{two} apart from \code{ONE} and \code{TWO}) }
1010+\p{This defines a type called \code{oot} with two values, \code{ONE : oot} and \code{TWO : oot}. The \code{print_theorems} command here allows us to see all of the theorems automatically created by the \code{datatype} command, chiefly that the constants \code{ONE} and \code{TWO} are \em{disjoint} (i.e. \code{ONE ≠ TWO}) and \em{exhaustive} (i.e. that there are no other values of type \code{oot} apart from \code{ONE} and \code{TWO}) }
+8-1
trees/isa/isa-001K.tree
···11\date{2025-12-02T12:59:55Z}
22\title{The \code{datatype} command}
33+\author{liamoc}
34\import{shiki-macros}
45\put\shiki/language{Isabelle Theory}
56\p{The \code{datatype} defines a new type (like \code{typedecl}) but also defines some special constants, called \em{constructors}, which make values of that type. Constructors may optionally take arguments, and these data types may be recursive. }
···78 | Constructor2 (* ... *)
89 (* ... *)
910}
1010-\p{These datatypes are analogous to the algebraic data types found in many functional programming languages.}1111+\p{These datatypes are analogous to the algebraic data types found in many functional programming languages.}
1212+\p{The \code{datatype} command automatically proves many lemmas about these types for you, chiefly:}
1313+\ul{
1414+\li{Disjointness: Values made with one constructor are not equal to values made with another constructor.}
1515+\li{Exhaustivity: The only values of this type are those made by the listed constructors.}
1616+\li{Injectivity: Two values of the same constructor are equal iff their arguments are equal.}
1717+}
+1-1
trees/isa/isa-001M.tree
···55\parent{isa-001B}
66\taxon{Example}
77\put\shiki/language{Isabelle Theory}
88-\shiki{lemma ‹f (f (f (b::two))) = f b›}
88+\shiki{lemma lm001M: ‹f (f (f (b::two))) = f b›}
99\solnblock{
1010\shiki{apply (case_tac b)
1111 apply simp
+7
trees/isa/isa-001N.tree
···11+\date{2025-12-03T02:35:03Z}
22+\title{Natural numbers in Isabelle}
33+\author{liamoc}
44+\import{shiki-macros}
55+\put\shiki/language{Isabelle Theory}
66+\p{Isabelle/HOL's [theory of natural numbers](https://isabelle.in.tum.de/library/HOL/HOL/Nat.html) defines natural numbers in a different way, but they behave much as if they were defined with [the \code{datatype} command](isa-001K). }
77+\shiki{datatype nat = 0 | Suc "nat"}
+23
trees/isa/isa-001O.tree
···11+\date{2025-12-03T02:48:14Z}
22+\import{shiki-macros}
33+\import{dt-macros}
44+\put\shiki/language{Isabelle Theory}
55+\title{Defining functions in Isabelle}
66+\p{The \code{fun} command can be used to define functions in Isabelle. Unlike [\code{definition}s](isa-001G), functions can be defined by \em{multiple} pattern-matching equations, they may be recursive, and their equations are automatically added to [the simpset](isa-001H).}
77+\subtree{\taxon{Example}\title{Fibonacci as a \code{fun}}\author{liamoc}
88+\shiki{fun fib :: "nat ⇒ nat" where
99+ "fib 0 = 0"
1010+| "fib (Suc 0) = Suc 0"
1111+| "fib (Suc (Suc n)) = fib n + fib (Suc n)"
1212+print_theorems}
1313+}
1414+\p{The \code{print_theorems} command allows us to see all of the lemmas generated by this command.
1515+}
1616+\problemblock{
1717+ \p{Isabelle functions must provably terminate. The problem with non-terminating functions can be illustrated by a definition like:}
1818+ \shiki{fun bad :: "nat ⇒ bool" where "bad x = ¬ (bad x)"}
1919+ \p{If such a non-terminating definition were allowed, this would render our logic inconsistent (as \code{bad x} is equal to its own negation). Therefore, Isabelle requires that all functions be accompanied by a proof of termination.}
2020+ \p{The \code{fun} command attempts to prove termination automatically. If it does not succeed, it will give an error message and fail to define the function. Manual proofs of termination can be supplied if the \code{function} command is used instead, but the \code{function} command is beyond the scope of this course. }
2121+}
2222+\p{In cases where the recursion and pattern matching follows exactly the structure of the datatype in one argument, \code{primrec} can be used instead of \code{fun}, which is a bit more efficient:}
2323+\transclude{isa-001R}
+8
trees/isa/isa-001P.tree
···11+\date{2025-12-03T03:46:57Z}
22+\author{liamoc}
33+\taxon{Proof Method}
44+\import{shiki-macros}
55+\put\shiki/language{Isabelle Theory}
66+\title{\code{induct} (for structural induction)}
77+\p{While it is possible to use \code{rule} or \code{erule} with the generated \code{.induct} theorem from a [\code{datatype}](isa-001K), it is usually much simpler and more convenient to use the \code{induct} proof method. Similar to the [[isa-001L]] method, \code{apply (induct t)} splits the goal into various cases, one for each constructor of the type of \code{t}. The difference is that for recursive cases of the datatype, we also get an \em{inductive hypothesis} added to our assumptions.}
88+\transclude{isa-001Q}
···11+\date{2025-12-03T03:55:43Z}
22+\taxon{Example}
33+\title{Factorial as a \code{primrec}}
44+\import{shiki-macros}
55+\put\shiki/language{Isabelle Theory}
66+\author{liamoc}
77+\shiki{primrec factorial :: "nat ⇒ nat" where
88+ "factorial 0 = Suc 0"
99+| "factorial (Suc n) = Suc n * factorial n"
1010+print_theorems}
+10
trees/isa/isa-001S.tree
···11+\date{2025-12-03T04:05:58Z}
22+\taxon{Example}
33+\author{liamoc}
44+\title{Higher-order functions}
55+\import{shiki-macros}
66+\put\shiki/language{Isabelle Theory}
77+\shiki{primrec rpt :: ‹('a ⇒ 'a) ⇒ nat ⇒ 'a ⇒ 'a› where
88+ ‹rpt f 0 x = x ›
99+| ‹rpt f (Suc n) x = f (rpt f n x)›}
1010+\p{The above function is given \em{another function} as an input.}
+19
trees/isa/isa-001T.tree
···11+\date{2025-12-03T04:10:30Z}
22+\author{liamoc}
33+\taxon{Exercise}
44+\import{shiki-macros}
55+\put\shiki/language{Isabelle Theory}
66+\import{dt-macros}
77+\parent{isa-001B}
88+\shiki{definition twice :: ‹('a ⇒ 'a) ⇒ 'a ⇒ 'a› where
99+‹twice f x = f (f x)›}
1010+\shiki{lemma ‹rpt (twice f) n (f (x::two)) = f x›}
1111+\solnblock{
1212+\shiki{apply (unfold twice_def)
1313+apply (induct n)
1414+ apply simp
1515+apply simp
1616+apply (rule lm001M)
1717+done}
1818+\p{Using the lemma from \ref{isa-001M}.}
1919+}
+12
trees/isa/isa-001U.tree
···11+\date{2025-12-03T04:29:49Z}
22+\author{liamoc}
33+\taxon{Definition}
44+\import{shiki-macros}
55+\put\shiki/language{Isabelle Theory}
66+\parent{isa-001B}
77+\title{The \code{oots} type}
88+\shiki{datatype oots =
99+ ONEs "nat" "oots"
1010+ | TWOs "nat" "oots"
1111+ | Empty}
1212+\p{This type encodes a sequence of [\code{oot}](isa-001J) values. For example, the value \code{ONEs 3 (TWOs 2 (ONEs 1 Empty))} encodes the sequence \code{[ONE, ONE, ONE, TWO, TWO, ONE]}. }
+14
trees/isa/isa-001V.tree
···11+\date{2025-12-03T04:41:52Z}
22+\author{liamoc}
33+\taxon{Definition}
44+\import{shiki-macros}
55+\put\shiki/language{Isabelle Theory}
66+\parent{isa-001B}
77+\title{The \code{prepend} function}
88+\shiki{fun prepend :: ‹oot ⇒ nat ⇒ oots ⇒ oots› where
99+ ‹prepend ONE n Empty = ONEs n Empty›
1010+| ‹prepend TWO n Empty = TWOs n Empty›
1111+| ‹prepend ONE n (TWOs m r) = ONEs n (TWOs m r)›
1212+| ‹prepend TWO n (ONEs m r) = TWOs n (ONEs m r)›
1313+| ‹prepend ONE n (ONEs m r) = ONEs (n+m) r›
1414+| ‹prepend TWO n (TWOs m r) = TWOs (n+m) r›}
+21
trees/isa/isa-001W.tree
···11+\date{2025-12-03T04:45:13Z}
22+\taxon{Theorem}
33+\import{dt-macros}
44+\import{shiki-macros}
55+\author{liamoc}
66+\title{\code{prepend_prepend}}
77+\parent{isa-001B}
88+\put\shiki/language{Isabelle Theory}
99+\shiki{lemma prepend_prepend: ‹prepend s n (prepend s m r) = prepend s (n + m) r›}
1010+\solnblock{
1111+\shiki{apply (case_tac s)
1212+ apply simp
1313+ apply (case_tac r)
1414+ apply simp
1515+ apply simp
1616+ apply simp
1717+ apply (case_tac r)
1818+ apply simp
1919+ apply simp
2020+apply simp
2121+done}}
+9
trees/isa/isa-001X.tree
···11+\date{2025-12-03T04:52:32Z}
22+\author{liamoc}
33+\title{Combining methods with semicolons}
44+\import{shiki-macros}
55+\put\shiki/language{Isabelle Theory}
66+\p{Methods can be combined using the \code{;} operator:}
77+\shiki{apply (m1; m2)}
88+\p{This applies \code{m2} to \em{every subgoal} that results from applying \code{m1} to the current goal. It can be chained together multiple times. For example, the entire proof of \ref{isa-001W} can be much more succinctly expressed as one line:}
99+\shiki{by (case_tac s; case_tac r; simp)}
+13
trees/isa/isa-001Y.tree
···11+\date{2025-12-03T04:58:18Z}
22+\author{liamoc}
33+\taxon{Definition}
44+\import{shiki-macros}
55+\put\shiki/language{Isabelle Theory}
66+\parent{isa-001B}
77+\title{The \code{cat} function}
88+\shiki{fun cat :: ‹oots ⇒ oots ⇒ oots› where
99+ ‹cat (ONEs n xs) ys = prepend ONE n (cat xs ys)›
1010+| ‹cat (TWOs n xs) ys = prepend TWO n (cat xs ys)›
1111+| ‹cat Empty ys = ys›
1212+}
1313+\p{This function uses [the \code{prepend} function](isa-001V) to concatenate two \code{oots} sequences together.}
+11
trees/isa/isa-001Z.tree
···11+\date{2025-12-03T05:07:08Z}
22+\author{liamoc}
33+\taxon{Theorem}
44+\import{shiki-macros}
55+\import{dt-macros}
66+\put\shiki/language{Isabelle Theory}
77+\parent{isa-001B}
88+\title{\code{cat_prepend}}
99+\shiki{lemma cat_prepend: ‹cat (prepend s n x) y = prepend s n (cat x y)›}
1010+\solnblock{
1111+ \shiki{by (case_tac s; case_tac x; simp add: prepend_prepend)}}
+11
trees/isa/isa-0020.tree
···11+\date{2025-12-03T05:09:52Z}
22+\author{liamoc}
33+\taxon{Theorem}
44+\import{shiki-macros}
55+\import{dt-macros}
66+\put\shiki/language{Isabelle Theory}
77+\parent{isa-001B}
88+\title{\code{cat_assoc}}
99+\shiki{lemma cat_assoc: ‹cat x (cat y z) = cat (cat x y) z›}
1010+\solnblock{\shiki{by (induct x;simp add: cat_prepend)}}
1111+
+15
trees/isa/isa-0021.tree
···11+\date{2025-12-03T05:16:30Z}
22+\author{liamoc}
33+\title{Lists in Isabelle}
44+\import{shiki-macros}
55+\put\shiki/language{Isabelle Theory}
66+\p{The Isabelle/HOL [theory of Lists](https://isabelle.in.tum.de/library/HOL/HOL/List.html) defines lists as follows:}
77+\shiki{datatype 'a list = Nil | Cons "'a" "'a list" }
88+\p{This is an example of a \em{polymorphic} data type, where the type variable \code{'a} stands for a type. For example, the type \code{nat list} is the type of lists of \code{nat}, and \code{oot list} is the type of a list of [\code{oot}s](isa-001J). }
99+\p{The notation \code{x#xs} is syntax sugar for \code{Cons x xs} and \code{[]} is syntax sugar for \code{Nil}. Lists can also be written in square brackets, so:}
1010+\shiki{[1,2,3]}
1111+\p{is equivalent to:}
1212+\shiki{1 # 2 # 3 # []}
1313+\p{which is equivalent to:}
1414+\shiki{Cons 1 (Cons 2 (Cons 3 Nil))}
1515+\p{Some provided functions are useful, including \code{replicate :: nat ⇒ 'a ⇒ 'a list}, which produces a list of #{n} copies of the given value, and \code{append :: 'a list ⇒ 'a list ⇒ 'a list} which joins two lists together into one. The \code{append} function also has special notation, so \code{a @ b} is equivalent to \code{append a b}}
+11
trees/isa/isa-0022.tree
···11+\date{2025-12-03T05:29:25Z}
22+\taxon{Definition}
33+\import{shiki-macros}
44+\put\shiki/language{Isabelle Theory}
55+\author{liamoc}
66+\parent{isa-001B}
77+\title{The \code{expand} function}
88+\shiki{primrec expand :: ‹oots ⇒ oot list› where
99+ ‹expand (ONEs n r) = replicate n ONE @ expand r›
1010+| ‹expand (TWOs n r) = replicate n TWO @ expand r›
1111+| ‹expand Empty = []›}
···11+\date{2025-12-03T06:15:34Z}
22+\author{liamoc}
33+\taxon{Example}
44+\import{shiki-macros}
55+\put\shiki/language{Isabelle Theory}
66+\title{Wellformedness for \code{oots}}
77+\p{We define \code{well}, an inductive wellformedness predicate for \code{oots} sequences, that state there are no segments of zero length, and that no two adjacent segments have the same \code{oot} value.}
88+\shiki{inductive well :: ‹oots ⇒ bool› where
99+ ‹well Empty›
1010+| ‹n > 0 ⟹ well (ONEs n Empty)›
1111+| ‹n > 0 ⟹ well (TWOs n Empty)›
1212+| ‹n > 0 ⟹ well (ONEs m r) ⟹ well (TWOs n (ONEs m r))›
1313+| ‹n > 0 ⟹ well (TWOs m r) ⟹ well (ONEs n (TWOs m r))›}