{"id":18495931,"url":"https://github.com/leanprover/vstte2024","last_synced_at":"2025-10-31T15:30:41.172Z","repository":{"id":257846389,"uuid":"865301469","full_name":"leanprover/vstte2024","owner":"leanprover","description":null,"archived":false,"fork":false,"pushed_at":"2024-10-15T15:12:26.000Z","size":61,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":9,"default_branch":"main","last_synced_at":"2024-12-25T17:10:06.656Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Lean","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leanprover.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-30T10:03:39.000Z","updated_at":"2024-11-08T19:41:20.000Z","dependencies_parsed_at":"2024-10-16T17:43:11.887Z","dependency_job_id":"0b710007-fb74-4940-8e08-9026875971cd","html_url":"https://github.com/leanprover/vstte2024","commit_stats":null,"previous_names":["leanprover/vstte2024"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leanprover%2Fvstte2024","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leanprover%2Fvstte2024/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leanprover%2Fvstte2024/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leanprover%2Fvstte2024/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leanprover","download_url":"https://codeload.github.com/leanprover/vstte2024/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239212561,"owners_count":19600830,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T13:26:52.493Z","updated_at":"2025-10-31T15:30:41.100Z","avatar_url":"https://github.com/leanprover.png","language":"Lean","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lean tutorial\n\nThis is the accompanying code for the invited lean tutorial held at [VSTTE\n2024](https://www.soundandcomplete.org/vstte2024.html) by Sebastian Ullrich and Joachim Breitner.\n\n[Introductory slides](https://docs.google.com/presentation/d/e/2PACX-1vRHeNJieYkbz4tWLce--Dm7GTRZvamSEMI1cmcPVEiJMphtDmaffJ7YENAOi6155ypt08DmifD7NYFK/pub?start=false\u0026loop=false\u0026delayms=3000)\n\n## Overview\n\nIn this tutorial we will see the following features of Lean\n\n* basic functional programming\n* extensible custom syntax for domain-specific functions\n* inductive predicates and proofs\n\nThe example use-case is a standard task in programming language theory: Embedding a small imperative\nlanguage, defining its semantics, and reasoning about it.\n\nWe won't have time to explain everything in complete detail, but we\nhope that the overview we provide is a good starting point for\nlearning to use Lean. Please see [the documentation\nsection](https://lean-lang.org/documentation/) of the Lean website for\nfurther resources. The [Lean Zulip](https://leanprover.zulipchat.com/)\nis a friendly and helpful place to ask questions for both beginners\nand experts.\n\n## Preparing for the Tutorial\n\nTo prepare for the tutorial, please do the following:\n\n1. [Install Lean](https://lean-lang.org/lean4/doc/quickstart.html)\n2. Clone this repository\n3. Ensure that you can build the code by running `lake build` from the\n   command line\n4. Ensure that your editor is correctly connected to Lean by opening\n   one of the files, introducing an error, and checking that there is\n   feedback\n\n## Hands-on tasks\n\nThe tutorial will be in live-coding presentation style, with breaks for hands-on experiences. Here\nare suggested tasks that you could try:\n\n### First hands-on break\n\nSuggested tasks, in rough order of difficulty. These are invitations to play around with Lean; unless you have prior experience with it or very similar tools like Isabelle or Coq, it is not likely to finisht them without help.\n\nThe branch `exercises` contains the result of solving all the exercises.\n\n* Add unary operations (negation, logical not) to the expression language.\n\n* Let `Expr.optimize` apply rules like `0 + x = x`, `1 * x = x`.\n\n  Hints:\n\n  - It may be helpful to define a (non-recursive) function `Expr.optOp` with the same type as\n    `Expr.op`, that serves as a “smart constructor”. Pattern matching can be elegant here!\n  - In general it is advisible to write a separate theorem about each involved function\n    (`BinOp.apply`, `Expr.optOp`, `Expr.optimize`) separately than to do it all in one go.\n    If these theorems are set up just right, they are good `@[simp]` lemmas, and will make the\n    subsequent proof easy.\n\n* Prove that `Expr.optimize` is idempotent: `(e : Expr) : e.optimize.optimize = e.optimize`.\n\n* Write a function `Expr.hasDiv : Expr → Bool` that checks if division is used in the expression.\n\n  Prove that if an expression has no division, then `Expr.eval` will always return a result.\n\n  Hint: There are various ways of phrasing this. You can use `Option.isSome` and write a theorem about\n  `Option.bind` and `Option.isSome`. Or you can define `Expr.eval'` that returns `Value` (no\n  `Option`) and prove that for expressions without division, the result of `Expr.eval` is\n  `Option.some` of the value returned by `Expr.eval'`.\n\n  Food for thought: How does this task relate to the previous task and the optimization `0 * x = 0`?\n  If you have done both tasks, can you combine them?\n\n\n### Second hands-on break\n\n* Add nice input syntax for `Env.get σ \"x\"` and `Env.set`, e.g. `σ[[x]]` and `σ[[x := e]]` and\n  update some of the proof statements.\n\n  Instead of `syntax` and `macro_rules` you can also try to use the `notation` command as documented\n  at \u003chttps://lean-lang.org/lean4/doc/notation.html\u003e; this will also make the new syntax show up in the InfoView (in other words, it will also delaborate).\n\n* Add the optimization that replaces `x := x` by `skip` to `Stmt.optimize`.\n\n  Use `#guard_msgs` to check that it does what you want it to do on a small example.\n\n  Finally, extend the verification proof.\n\n  Hints:\n\n  You may want to prove `@[simp] theorem set_get_same {σ : Env} : σ.set x (σ.get x) = σ` for that.\n  To prove an equality on `Env`, add the `@[ext]` attribute to the `Env` structure. This will allow\n  you to use `apply Env.ext` (or even start the proof with `ext y : 2` – check the docstring to see what that does.)\n\n* (Short but tricky):\n\n  Complete this proof that a looping program has no output\n  ```lean\n  def loop := imp {while (1) {skip;}}\n  theorem infinite_loop : ¬ BigStep σ loop σ' := by\n  ```\n\n  Hint:\n\n  Rephrase the statement so that the three arguments to `BigStep` are variables, so that `induction` works. You can do that using a helper theorem that you finally apply, or explore the `generalize` tactic.\n\n## Code Structure\n\n - `Imp/Expr.lean` re-exports the expression language:\n   - `Imp/Expr/Basic.lean` contains the AST of expressions\n   - `Imp/Expr/Eval.lean` contains an evaluator for expressions\n   - `Imp/Expr/Optimize.lean` contains a formally verified optimization pass\n   - `Imp/Expr/Syntax.lean` adds a more convenient syntax for expressions\n   - `Imp/Expr/Delab.lean` causes Lean to use the convenient syntax in\n     its output (not part of tutorial, but nice to have!)\n - `Imp/Stmt.lean` re-exports the statement language:\n   - `Imp/Stmt/Basic.lean` contains the AST and a convenient concrete\n     syntax for statements\n   - `Imp/Stmt/Delab.lean` causes Lean to use the convenient concrete\n     syntax in its output (not part of tutorial, but nice to have!)\n   - `Imp/Stmt/Optimize.lean` contains an optimization pass (unverified)\n   - `Imp/Stmt/BigStep.lean` contains big-step operational semantics,\n     and uses them to prove the optimizer correct. It also contains a\n     function that implements these semantics, which can be used to\n     run programs.\n - `Imp.lean` imports the other libraries, and contains a concluding\n   demo of using a verified bit blaster to quickly prove theorems.\n\n## Acknowledgments\n\nThis content is based on [material written by David Thrane\nChristiansen](https://github.com/david-christiansen/lean-fkbh-24-2) for the tutorial \"Lean for the\nFunctional Programmer\", presented at *Mødegruppen for F#unktionelle Københavnere* by David Thrane\nChristiansen on 2024-08-27 and 2024-09-24.\n\nThis material itself is based on a tutorial presented at [SSFT24](https://fm.csl.sri.com/SSFT24/) by\nDavid Thrane Christiansen, co-developed with Leonardo de Moura.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleanprover%2Fvstte2024","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleanprover%2Fvstte2024","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleanprover%2Fvstte2024/lists"}