Skip to content

Commit

Permalink
chore: make 'while' available earlier (leanprover#5784)
Browse files Browse the repository at this point in the history
  • Loading branch information
kim-em authored Oct 21, 2024
1 parent 5d155d8 commit 4f18c29
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 36 deletions.
1 change: 1 addition & 0 deletions src/Init.lean
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ import Init.Ext
import Init.Omega
import Init.MacroTrace
import Init.Grind
import Init.While
37 changes: 1 addition & 36 deletions src/Init/NotationExtra.lean
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Init.Data.ToString.Basic
import Init.Data.Array.Subarray
import Init.Conv
import Init.Meta
import Init.While

namespace Lean

Expand Down Expand Up @@ -344,42 +345,6 @@ syntax (name := solveTactic) "solve" withPosition((ppDedent(ppLine) colGe "| " t
macro_rules
| `(tactic| solve $[| $ts]* ) => `(tactic| focus first $[| ($ts); done]*)

/-! # `repeat` and `while` notation -/

inductive Loop where
| mk

@[inline]
partial def Loop.forIn {β : Type u} {m : Type u → Type v} [Monad m] (_ : Loop) (init : β) (f : Unit → β → m (ForInStep β)) : m β :=
let rec @[specialize] loop (b : β) : m β := do
match ← f () b with
| ForInStep.done b => pure b
| ForInStep.yield b => loop b
loop init

instance : ForIn m Loop Unit where
forIn := Loop.forIn

syntax "repeat " doSeq : doElem

macro_rules
| `(doElem| repeat $seq) => `(doElem| for _ in Loop.mk do $seq)

syntax "while " ident " : " termBeforeDo " do " doSeq : doElem

macro_rules
| `(doElem| while $h : $cond do $seq) => `(doElem| repeat if $h : $cond then $seq else break)

syntax "while " termBeforeDo " do " doSeq : doElem

macro_rules
| `(doElem| while $cond do $seq) => `(doElem| repeat if $cond then $seq else break)

syntax "repeat " doSeq ppDedent(ppLine) "until " term : doElem

macro_rules
| `(doElem| repeat $seq until $cond) => `(doElem| repeat do $seq:doSeq; if $cond then break)

macro:50 e:term:51 " matches " p:sepBy1(term:51, " | ") : term =>
`(((match $e:term with | $[$p:term]|* => true | _ => false) : Bool))

Expand Down
51 changes: 51 additions & 0 deletions src/Init/While.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import Init.Core

/-!
# Notation for `while` and `repeat` loops.
-/

namespace Lean

/-! # `repeat` and `while` notation -/

inductive Loop where
| mk

@[inline]
partial def Loop.forIn {β : Type u} {m : Type u → Type v} [Monad m] (_ : Loop) (init : β) (f : Unit → β → m (ForInStep β)) : m β :=
let rec @[specialize] loop (b : β) : m β := do
match ← f () b with
| ForInStep.done b => pure b
| ForInStep.yield b => loop b
loop init

instance : ForIn m Loop Unit where
forIn := Loop.forIn

syntax "repeat " doSeq : doElem

macro_rules
| `(doElem| repeat $seq) => `(doElem| for _ in Loop.mk do $seq)

syntax "while " ident " : " termBeforeDo " do " doSeq : doElem

macro_rules
| `(doElem| while $h : $cond do $seq) => `(doElem| repeat if $h : $cond then $seq else break)

syntax "while " termBeforeDo " do " doSeq : doElem

macro_rules
| `(doElem| while $cond do $seq) => `(doElem| repeat if $cond then $seq else break)

syntax "repeat " doSeq ppDedent(ppLine) "until " term : doElem

macro_rules
| `(doElem| repeat $seq until $cond) => `(doElem| repeat do $seq:doSeq; if $cond then break)

end Lean

0 comments on commit 4f18c29

Please sign in to comment.