Lean4勉強メモ
Lean 4の勉強メモを記します。可能であれば、私がある程度理解しているHaskellと比較してみます。
Hello, world!
Lean4
def main : IO Unit := IO.println "Hello, world!"
> lean --run .\test.lean
Hello, world!
Haskell
main :: IO ()
main = putStrLn "Hello, world!"
入力した文字列を受け取って挨拶するコードを書いてみた。本当は下のコードでHello, John!
と表示されてほしかったが、getLine
だと改行まで含まれてしまうようで、意図しない結果になった。
def main : IO Unit := do
IO.print "name: "
let stdin ← IO.getStdin
let input ← stdin.getLine
IO.println s!"Hello, {input}!"
> lean --run .\Main.lean
name: John
Hello, John
!
>
String.dropRightWhile
とChar.isWhitespace
を使えば良いことがわかった。
というか、公式チュートリアルに普通に書いてあった。
これで文字列の末尾からスペース・タブ・改行コードを除くことができる。
def main : IO Unit := do
IO.print "name: "
let stdin ← IO.getStdin
let input ← stdin.getLine
let name := input.dropRightWhile Char.isWhitespace
IO.println s!"Hello, {name}!"
> lean --run .\Main.lean
name: John
Hello, John!
>
排中律の二重否定の証明
Lean4は基本的には直観主義論理(構成的論理)なので、そのままでは排中律(the law of excluded middle)は証明できません。名前空間Classical
を用いると、排中律等の古典論理の法則を利用できます。[1]
一方で、排中律の二重否定は直観主義論理で証明できるらしいので、今回はその証明に挑戦してみました。
theorem double_negate_excluded_middle (p : Prop) : ¬¬(p ∨ ¬ p) :=
fun nem : ¬(p ∨ ¬p) => show False from nem (
Or.inr (fun hp : p => show False from (nem (Or.inl hp)))
)
#print double_negate_excluded_middle
日本語で書き下すと、以下のような感じです。
定理(排中律の二重否定)
任意の命題
証明
まず、
そのために、
仮定
Lean4のコードの最後に#print double_negate_excluded_middle
と書きましたが、これによって、VS Codeの右側(Lean Infoview)に定理の証明が表示されるようです。
All Messages (1)
Main.lean:6:0
theorem double_negate_excluded_middle : ∀ (p : Prop), ¬¬(p ∨ ¬p) :=
fun p nem =>
let_fun this :=
nem
(Or.inr fun hp =>
let_fun this := nem (Or.inl hp);
this);
this
自分で書いたものとは少し違う証明が表示されました。
感想
Lean4、直観主義論理の良い練習となりました。
tactic-styleでも書いてみた。
theorem double_negate_excluded_middle (p : Prop) : ¬¬(p ∨ ¬p) := by
intro h1
apply h1
apply Or.inr
intro h2
apply h1
apply Or.inl
assumption