ここでの課題は、自作のリスト反転関数と組み込みのList.reverseが等しいことを証明することです。
この演習の性質上、従来のような実行時のテストではなく、checkという定理によって証明が検証されます。
この定理の型チェックが通れば、テストに合格したと考えてよいでしょう。
ローカルで取り組む場合も、Leanのオンラインプレイグラウンドで取り組む場合も、Lean InfoViewを通じて、それぞれの定理が成功したか失敗したか、そして失敗した理由について、すぐにフィードバックが得られます。 これは非常に役立つツールで、証明で使われているすべてのローカルの値や、現在のゴールを表示できます。
sorryタクティクを使うと、どんな証明も正しいように見えてしまいます。
そのため、証明を実際に書く前にcheck定理の型チェックが自動で通ったように見えることがあります。
証明からsorryを削除すれば、Lean InfoViewが正しいフィードバックを表示します。
定理の証明は、Leanに欠かせない要素です。プログラマーはこれを使って、自分のプログラムが持つ性質を証明したり、その振る舞いについて筋道立てて考えたり、制約や仕様を型のレベルで表現したりできます。
こちらの章は、Leanでの定理証明のよい入門になっています。さらに深く学びたい場合は、Leanの公式サイトで公式リソースとして紹介されているこちらの書籍がおすすめです。
Leanには、証明の全体または一部を自動化できるタクティクがたくさん用意されています。言語リファレンスを確認してみてもよいでしょう。
2つの定義が等しいことを証明する定理に、コンパイラ属性csimpを使うことができます。この属性は、コンパイラに、1つ目の定義の代わりに2つ目の定義を使うよう指示します。
@[csimp]
theorem custom_reverse_eq_spec_reverse : @Extra.custom_reverse = @List.reverse := by
... -- proof here
-- now any occurrence of `Extra.custom_reverse` may now compile to `List.reverse`.
実装はより効率的だがその分わかりにくい、という場面で特に役立ちます。シンプルな仕様を書き、コンパイルされたコードには代わりに効率のよい実装を使わせることができます。ListやArrayの多くの関数がこのパターンを使っています。