theory First_Taste_Of_Isabelle (*Note name of theory matches filename*)
imports Main (*Main theory imports most of Isabelle's standard library*)
begin
section\A taste of Isabelle\
(*this is a comment...*)
datatype natural
= Zero
| Succ "natural"
(*type checking Zero and Succ*)
term Zero
term Succ
term "Succ (Zero)"
(*print output of datatype command*)
print_theorems
(*consulting theorems by name*)
thm natural.induct
thm natural.distinct
thm natural.inject
(*recursive function defined by equations via pattern matching*)
fun add :: "natural \ natural \ natural" where
"add Zero n = n" |
"add (Succ m) n = Succ (add m n)"
(*note how Isabelle spots the termination argument automatically!*)
print_theorems
thm add.simps
term "add Zero (Succ m)"
(*computing with definitions, including support for symbolic computation*)
value "add (Succ Zero) (Succ (Succ Zero))"
value "add (Succ (Succ Zero)) (Succ m)"
lemma
shows "add m Zero = m"
apply(induction m rule: natural.induct) (*"induction" starts an induction proof*)
apply simp (*"simp" uses rewriting and simplification on current goal*)
apply simp
done
(*note that "simp" knows about add's equations above*)
lemma
shows "add m Zero = m"
apply(induction m) (*induction method guesses induction rule to apply*)
apply auto (*auto: powerful case splitting, rewriting, etc. across all goals*)
done
lemma add_ident [simp]: (*[simp] attribute: Isabelle's simplifier will use this theorem henceforth*)
shows "add m Zero = m"
by(induction m, auto) (*one line proof*)
thm add_ident
lemma
shows "add m n = add n m"
apply(induction m)
apply simp
apply simp (*stuck...*)
oops (*oops: abort the proof and discard the conjecture*)
lemma add_Succ [simp]:
shows "add m (Succ n) = Succ (add m n)"
apply(induction m)
apply simp
apply simp
done
(*structured proof using Isar:*)
lemma add_comm:
shows "add m n = add n m"
proof(induction m)
show "add Zero n = add n Zero"
by simp
next
fix m
assume IH: "add m n = add n m"
have "add (Succ m) n = Succ (add m n)"
by simp
moreover have "... = Succ (add n m)"
using IH by simp
moreover have "... = add n (Succ m)"
by simp
ultimately show "add (Succ m) n = add n (Succ m)"
by metis (*metis method: paramodulation based proof search*)
qed
(*a theorem with assumptions*)
lemma add_Zero_args_Zero:
assumes "add m n = Zero" (*assumes keyword: introduce an assumption*)
shows "n = Zero"
using assms by(induction m, auto)
(*"assumes ... shows ..." gets mapped to an "\" implication:*)
thm add_Zero_args_Zero
(*tight integration with underlying ML substrate via system of (anti)quotations*)
ML\
val z = @{code Zero}
val s = @{code Succ}
fun from_int 0 = z
| from_int m =
if m > 0 then
s (from_int (m - 1))
else raise Match
(*val a = from_int 53*)
(*val b = from_int 32*)
(*val c = @{code add} a b*)
(*val d = c = from_int 85*)
(*val _ = from_int (~4)*)
\
(*definitions can be exported to SML, OCaml, Haskell, and Scala*)
export_code add in SML
export_code add in Haskell
export_code add in OCaml
export_code add in Scala
(*Isabelle comes with a huge library of formal mathematics: *)
(*theorem search based on patterns and name of theorem*)
find_theorems "?x + ?y = ?y + ?x"
find_theorems name: Group
find_theorems "?x + ?y = ?y + ?x" name: Group
(*constant search based on type and name of constant*)
find_consts "'a list \ 'a" name: List
find_consts "'a set set \ 'a set"
find_consts "int \ int"
end