open Lean
/- Disable the automatic monadic lifting feature described in the paper. We want to make it clear that we do not depend on it. -/set_option autoLift falsesyntax"for" ident "in" term "do'" stmt:1 : stmt
syntax"break " : stmt
syntax"continue " : stmt
syntax"break" : expander
syntax"continue" : expander
syntax"lift" : expander
macro_rules|`(stmt|expand!$_ inbreak) =>
Monad: (Type ?u.36846 → Type ?u.36845) → Type (max (?u.36846 + 1) ?u.36845)
Monad
m: Type ?u.7311 → Type ?u.7310
m]
variable (
ma: m α
ma
ma': m α
ma' :
m: Type ?u.7322 → Type ?u.7321
m
α: Type
α)
variable (
b: Bool
b :
Bool: Type
Bool)
variable (
xs: List α
xs :
List: Type → Type
List
α: Type
α) (
act: α → m Unit
act :
α: Type
α→
m: Type → Type u_1
m
Unit: Type
Unit)
attribute [localsimp]
map_eq_pure_bind: ∀ {m : Type u_1 → Type u_2} {α β : Type u_1} [inst : Monad m] [inst_1 : LawfulMonad m] (f : α → β) (x : m α),
f <$> x = do
let a ← x
pure (f a)
map_eq_pure_bind
example: ∀ {m : Type → Type u_1} {α : Type} [inst : Monad m] (xs : List α) (act : α → m Unit) [inst_1 : LawfulMonad m],
(forM xs fun x => act x) = List.forM xs act
example [
LawfulMonad: (m : Type → Type u_1) → [inst : Monad m] → Prop
LawfulMonad
m: Type → Type u_1
m] :
(do'for
x: α
xin
xs: List α
xsdo' {
act: α → m Unit
act
x: α
x
})
=
xs: List α
xs.
forM: {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → List α → (α → m PUnit) → m PUnit
forM
act: α → m Unit
act
:=
m: Type→Type?u.7430 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit
(forM xs fun x => act x) = List.forM xs act
m: Type→Type?u.7430 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit
nil
(forM [] fun x => act x) = List.forM [] act
m: Type→Type?u.7430 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit head✝: α tail✝: List α
(forM (head✝ :: tail✝) fun x => act x) = List.forM (head✝ :: tail✝) act
m: Type→Type?u.7430 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit
nil
(forM [] fun x => act x) = List.forM [] act
m: Type→Type?u.7430 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit head✝: α tail✝: List α
(forM (head✝ :: tail✝) fun x => act x) = List.forM (head✝ :: tail✝) act
Goals accomplished!🐙
def
ex2: {β : Type} → (β → α → m β) → β → List α → m β
ex2 (
f: β → α → m β
f :
β: Type
β→
α: Type
α→
m: Type → Type u_1
m
β: Type
β) (
init: β
init :
β: Type
β) (
xs: List α
xs :
List: Type → Type
List
α: Type
α) :
m: Type → Type u_1
m
β: Type
β := do'letmut
y: β
y :=
init: β
init;for
x: α
xin
xs: List α
xsdo' {
y ←
f: β → α → m β
f
y: β
y
x: α
x
};return
y: β
y
example: ∀ {m : Type → Type u_1} {α : Type} [inst : Monad m] (xs : List α) {β : Type} {init : β} [inst_1 : LawfulMonad m]
(f : β → α → m β), ex2 f init xs = List.foldlM f init xs
example [
LawfulMonad: (m : Type ?u.8985 → Type ?u.8984) → [inst : Monad m] → Prop
LawfulMonad
m: Type → Type u_1
m] (
f: β → α → m β
f :
β: Type
β→
α: Type
α→
m: Type → Type u_1
m
β: Type
β) :
ex2: {m : Type → Type u_1} → {α : Type} → [inst : Monad m] → {β : Type} → (β → α → m β) → β → List α → m β
ex2
f: β → α → m β
f
init: β
init
xs: List α
xs=
xs: List α
xs.
foldlM: {m : Type → Type u_1} → [inst : Monad m] → {s α : Type} → (s → α → m s) → s → List α → m s
foldlM
f: β → α → m β
f
init: β
init :=
m: Type→Type?u.8948 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit β: Type init: β f: β → α → m β
ex2 f init xs = List.foldlM f init xs
m: Type→Type?u.8948 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit β: Type init: β f: β → α → m β
ExceptCpsT.runCatch
(let y := init;
StateT.run'
(do
forM xs fun x =>dolet y ← get
let y ← StateT.lift (ExceptCpsT.lift (f y x))
let _ ← get
set y
let y ← get
StateT.lift (throw y))
y) =
List.foldlM f init xs
;
m: Type→Type?u.8948 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit β: Type f: β → α → m β init: β
nil
ExceptCpsT.runCatch
(let y := init;
StateT.run'
(do
forM [] fun x =>dolet y ← get
let y ← StateT.lift (ExceptCpsT.lift (f y x))
let _ ← get
set y
let y ← get
StateT.lift (throw y))
y) =
List.foldlM f init []
m: Type→Type?u.8948 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit β: Type f: β → α → m β head✝: α tail✝: List α init: β
ExceptCpsT.runCatch
(let y := init;
StateT.run'
(do
forM (head✝ :: tail✝) fun x =>dolet y ← get
let y ← StateT.lift (ExceptCpsT.lift (f y x))
let _ ← get
set y
let y ← get
StateT.lift (throw y))
y) =
List.foldlM f init (head✝ :: tail✝)
m: Type→Type?u.8948 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit β: Type f: β → α → m β init: β
nil
ExceptCpsT.runCatch
(let y := init;
StateT.run'
(do
forM [] fun x =>dolet y ← get
let y ← StateT.lift (ExceptCpsT.lift (f y x))
let _ ← get
set y
let y ← get
StateT.lift (throw y))
y) =
List.foldlM f init []
m: Type→Type?u.8948 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit β: Type f: β → α → m β head✝: α tail✝: List α init: β
ExceptCpsT.runCatch
(let y := init;
StateT.run'
(do
forM (head✝ :: tail✝) fun x =>dolet y ← get
let y ← StateT.lift (ExceptCpsT.lift (f y x))
let _ ← get
set y
let y ← get
StateT.lift (throw y))
y) =
List.foldlM f init (head✝ :: tail✝)
Goals accomplished!🐙
@[simp] theorem
List.find?_cons: ∀ {x : α} {p : α → Bool} {xs : List α}, find? p (x :: xs) = if p x = true then some x else find? p xs
m: Type→Type?u.17767 α: Type inst✝: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit x: α p: α → Bool xs: List α
find? p (x :: xs) =if p x = true then some x else find? p xs
m: Type→Type?u.17767 α: Type inst✝: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit x: α p: α → Bool xs: List α h: p x = false
false
find? p (x :: xs) =if false = true then some x else find? p xs
m: Type→Type?u.17767 α: Type inst✝: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit x: α p: α → Bool xs: List α h: p x = true
find? p (x :: xs) =if true = true then some x else find? p xs
m: Type→Type?u.17767 α: Type inst✝: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit x: α p: α → Bool xs: List α h: p x = false
false
find? p (x :: xs) =if false = true then some x else find? p xs
m: Type→Type?u.17767 α: Type inst✝: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit x: α p: α → Bool xs: List α h: p x = true
find? p (x :: xs) =if true = true then some x else find? p xs
Goals accomplished!🐙
example: ∀ {α : Type} (xs : List α) (p : α → Bool),
Id.run
(ExceptCpsT.runCatch do
forM xs fun x => if p x = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.find? p xs
example (
p: α → Bool
p :
α: Type
α→
Bool: Type
Bool) :
Id.run: {α : Type} → Id α → α
Id.run
(do'for
x: α
xin
xs: List α
xsdo' {
if
p: α → Bool
p
x: α
xthen {
return
some: {α : Type} → α → Option α
some
x: α
x
}
};
pure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f α
m: Type→Type?u.18571 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → Bool
Id.run
(ExceptCpsT.runCatch do
forM xs fun x =>if p x = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.find? p xs
m: Type→Type?u.18571 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → Bool
Id.run
(ExceptCpsT.runCatch do
forM xs fun x =>if p x = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.find? p xs
m: Type→Type?u.18571 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → Bool
nil
Id.run
(ExceptCpsT.runCatch do
forM [] fun x =>if p x = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.find? p []
Goals accomplished!🐙
m: Type→Type?u.18571 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → Bool x: α tail✝: List α
cons
Id.run
(ExceptCpsT.runCatch do
forM (x :: tail✝) fun x =>if p x = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.find? p (x :: tail✝)
m: Type→Type?u.18571 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → Bool x: α tail✝: List α h: p x = false
cons.false
Id.run
(ExceptCpsT.runCatch do
forM (x :: tail✝) fun x =>if p x = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.find? p (x :: tail✝)
m: Type→Type?u.18571 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → Bool x: α tail✝: List α h: p x = true
Id.run
(ExceptCpsT.runCatch do
forM (x :: tail✝) fun x =>if p x = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.find? p (x :: tail✝)
m: Type→Type?u.18571 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → Bool x: α tail✝: List α h: p x = false
cons.false
Id.run
(ExceptCpsT.runCatch do
forM (x :: tail✝) fun x =>if p x = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.find? p (x :: tail✝)
m: Type→Type?u.18571 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → Bool x: α tail✝: List α h: p x = true
Id.run
(ExceptCpsT.runCatch do
forM (x :: tail✝) fun x =>if p x = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.find? p (x :: tail✝)
Goals accomplished!🐙
variable (
p: α → m Bool
p :
α: Type
α→
m: Type → Type ?u.38841
m
Bool: Type
Bool)
theorem
byCases_Bool_bind: ∀ {m : Type → Type u_1} [inst : Monad m] {β : Type} (x : m Bool) (f g : Bool → m β),
f true = g true → f false = g false → x >>= f = x >>= g
byCases_Bool_bind (
x: m Bool
x :
m: Type → Type u_1
m
Bool: Type
Bool) (
f: Bool → m β
f
g: Bool → m β
g :
Bool: Type
Bool→
m: Type → Type u_1
m
β: Type
β) (
isTrue: f true = g true
isTrue :
f: Bool → m β
f
true: Bool
true=
g: Bool → m β
g
true: Bool
true) (
isFalse: f false = g false
isFalse :
f: Bool → m β
f
false: Bool
false=
g: Bool → m β
g
false: Bool
false) : (
x: m Bool
x>>=
f: Bool → m β
f) = (
x: m Bool
x>>=
g: Bool → m β
g) :=
m: Type→Type u_1 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool β: Type x: m Bool f, g: Bool → m β isTrue: f true = g true isFalse: f false = g false
x >>= f = x >>= g
m: Type→Type u_1 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool β: Type x: m Bool f, g: Bool → m β isTrue: f true = g true isFalse: f false = g false
x >>= f = x >>= g
m: Type→Type u_1 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool β: Type x: m Bool f, g: Bool → m β isTrue: f true = g true isFalse: f false = g false
f = g
m: Type→Type u_1 α: Type inst✝: Monad m ma, ma': m α b✝: Bool xs: List α act: α → m Unit p: α → m Bool β: Type x: m Bool f, g: Bool → m β isTrue: f true = g true isFalse: f false = g false b: Bool
h
f b = g b
m: Type→Type u_1 α: Type inst✝: Monad m ma, ma': m α b✝: Bool xs: List α act: α → m Unit p: α → m Bool β: Type x: m Bool f, g: Bool → m β isTrue: f true = g true isFalse: f false = g false b: Bool
h
f b = g b
m: Type→Type u_1 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool β: Type x: m Bool f, g: Bool → m β isTrue: f true = g true isFalse: f false = g false
h.true
f true = g true
Goals accomplished!🐙
m: Type→Type u_1 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool β: Type x: m Bool f, g: Bool → m β isTrue: f true = g true isFalse: f false = g false
h.false
f false = g false
Goals accomplished!🐙
m: Type→Type u_1 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool β: Type x: m Bool f, g: Bool → m β isTrue: f true = g true isFalse: f false = g false this: f = g
x >>= f = x >>= g
m: Type→Type u_1 α: Type inst✝: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool β: Type x: m Bool f, g: Bool → m β isTrue: f true = g true isFalse: f false = g false this: f = g
x >>= g = x >>= g
Goals accomplished!🐙
theorem
eq_findM: ∀ {m : Type → Type u_1} {α : Type} [inst : Monad m] (xs : List α) (p : α → m Bool) [inst_1 : LawfulMonad m],
(ExceptCpsT.runCatch do
forM xs fun x => do
let b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
eq_findM [
LawfulMonad: (m : Type → Type u_1) → [inst : Monad m] → Prop
LawfulMonad
m: Type → Type u_1
m] :
(do'for
x: α
xin
xs: List α
xsdo' {
let
b: Bool
b←
p: α → m Bool
p
x: α
x;if
b: Bool
bthen {
return
some: {α : Type} → α → Option α
some
x: α
x
}
};
pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure
none: {α : Type} → Option α
none)
=
xs: List α
xs.
findM?: {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → (α → m Bool) → List α → m (Option α)
findM?
p: α → m Bool
p
:=
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool
(ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool
(ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool
nil
(ExceptCpsT.runCatch do
forM [] fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p []
Goals accomplished!🐙
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
cons
(ExceptCpsT.runCatch do
forM (x :: xs) fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p (x :: xs)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
cons
(ExceptCpsT.runCatch do
forM (x :: xs) fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p (x :: xs)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
cons
(ExceptCpsT.runCatch do
forM (x :: xs) fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ← p x
match a with| true => pure (some x)
| false => List.findM? p xs
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
cons
(ExceptCpsT.runCatch do
forM (x :: xs) fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ← p x
match a with| true => pure (some x)
| false =>
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
cons
(ExceptCpsT.runCatch do
forM (x :: xs) fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ← p x
match a with| true => pure (some x)
| false =>
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
;
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
cons
(dolet a ← p x
ExceptCpsT.runCatch doif a = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ← p x
match a with| true => pure (some x)
| false =>
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
cons.isTrue
(ExceptCpsT.runCatch doif true = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =match true with| true => pure (some x)
| false =>
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
(ExceptCpsT.runCatch doif false = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =match false with| true => pure (some x)
| false =>
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
cons.isTrue
(ExceptCpsT.runCatch doif true = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =match true with| true => pure (some x)
| false =>
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findM? p xs
(ExceptCpsT.runCatch doif false = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =match false with| true => pure (some x)
| false =>
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
Goals accomplished!🐙
def
ex3: [inst : Monad m] → (α → m Bool) → List (List α) → m (Option α)
ex3 [
Monad: (Type → Type u_1) → Type (max 1 u_1)
Monad
m: Type → Type u_1
m] (
p: α → m Bool
p :
α: Type
α→
m: Type → Type u_1
m
Bool: Type
Bool) (
xss: List (List α)
xss :
List: Type → Type
List (
List: Type → Type
List
α: Type
α)) :
m: Type → Type u_1
m (
Option: Type → Type
Option
α: Type
α) := do'for
xs: List α
xsin
xss: List (List α)
xssdo' {
for
x: α
xin
xs: List α
xsdo' {
let
b: Bool
b←
p: α → m Bool
p
x: α
x;if
b: Bool
bthen {
return
some: {α : Type} → α → Option α
some
x: α
x
}
}
};
pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure
none: {α : Type} → Option α
nonetheorem
eq_findSomeM_findM: ∀ {m : Type → Type u_1} {α : Type} [inst : Monad m] (p : α → m Bool) [inst_1 : LawfulMonad m] (xss : List (List α)),
ex3 p xss = List.findSomeM? (fun xs => List.findM? p xs) xss
eq_findSomeM_findM [
LawfulMonad: (m : Type → Type u_1) → [inst : Monad m] → Prop
LawfulMonad
m: Type → Type u_1
m] (
xss: List (List α)
xss :
List: Type → Type
List (
List: Type → Type
List
α: Type
α)) :
ex3: {m : Type → Type u_1} → {α : Type} → [inst : Monad m] → (α → m Bool) → List (List α) → m (Option α)
ex3
p: α → m Bool
p
xss: List (List α)
xss=
xss: List (List α)
xss.
findSomeM?: {m : Type → Type u_1} → [inst : Monad m] → {α β : Type} → (α → m (Option β)) → List α → m (Option β)
findSomeM? (fun
xs: List α
xs=>
xs: List α
xs.
findM?: {m : Type → Type u_1} → [inst : Monad m] → {α : Type} → (α → m Bool) → List α → m (Option α)
findM?
p: α → m Bool
p) :=
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool xss: List (List α)
ex3 p xss = List.findSomeM? (fun xs => List.findM? p xs) xss
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool xss: List (List α)
(ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) xss
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool xss: List (List α)
(ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) xss
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool
nil
(ExceptCpsT.runCatch do
forM [] fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) []
Goals accomplished!🐙
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xs: List α xss: List (List α) ih: (ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) xss
cons
(ExceptCpsT.runCatch do
forM (xs :: xss) fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) (xs :: xss)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xs: List α xss: List (List α) ih: (ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) xss
cons
(ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ← List.findM? p xs
match a with| some b => pure (some b)
| none => List.findSomeM? (fun xs => List.findM? p xs) xss
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xs: List α xss: List (List α) ih: (ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) xss
cons
(ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ← List.findM? p xs
match a with| some b => pure (some b)
| none => List.findSomeM? (fun xs => List.findM? p xs) xss
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xs: List α xss: List (List α) ih: (ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) xss
cons
(ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ← List.findM? p xs
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xs: List α xss: List (List α) ih: (ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) xss
cons
(ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xs: List α xss: List (List α) ih: (ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) xss
cons
(ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xs: List α xss: List (List α) ih: (ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) xss
cons
(ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool xss: List (List α) ih: (ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =
List.findSomeM? (fun xs => List.findM? p xs) xss
cons.nil
(ExceptCpsT.runCatch do
forM [] fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM [] fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
Goals accomplished!🐙
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xss: List (List α) x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
cons.cons
(ExceptCpsT.runCatch do
forM (x :: xs) fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM (x :: xs) fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xss: List (List α) x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
cons.cons
(dolet a ← p x
ExceptCpsT.runCatch doif a = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet x_1 ← p x
let a ←
ExceptCpsT.runCatch doif x_1 = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
;
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xss: List (List α) x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
cons.cons.isTrue
(ExceptCpsT.runCatch doif true = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch doif true = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xss: List (List α) x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
(ExceptCpsT.runCatch doif false = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch doif false = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xss: List (List α) x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
cons.cons.isTrue
(ExceptCpsT.runCatch doif true = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch doif true = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool xss: List (List α) x: α xs: List α ih: (ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch do
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
(ExceptCpsT.runCatch doif false = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)) =dolet a ←
ExceptCpsT.runCatch doif false = true then throw (some x) else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
match a with| some b => pure (some b)
| none =>
ExceptCpsT.runCatch do
forM xss fun xs =>
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw (some x) else ExceptCpsT.lift (pure ())
ExceptCpsT.lift (pure none)
Goals accomplished!🐙
def
List.untilM: {m : Type → Type u_1} → {α : Type} → [inst : Monad m] → (α → m Bool) → List α → m Unit
List.untilM (
p: α → m Bool
p :
α: Type
α→
m: Type → Type u_1
m
Bool: Type
Bool) :
List: Type → Type
List
α: Type
α→
m: Type → Type u_1
m
Unit: Type
Unit| [] =>
pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure
(): Unit
()|
a: α
a::
as: List α
as=>
p: α → m Bool
p
a: α
a>>=fun|
true: Bool
true=>
pure: {f : Type → Type u_1} → [self : Pure f] → {α : Type} → α → f α
pure
(): Unit
()|
false: Bool
false=>
as: List α
as.
untilM: (α → m Bool) → List α → m Unit
untilM
p: α → m Bool
ptheorem
eq_untilM: ∀ [inst : LawfulMonad m],
ExceptCpsT.runCatch
(forM xs fun x => do
let b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =
List.untilM p xs
eq_untilM [
LawfulMonad: (m : Type → Type u_1) → [inst : Monad m] → Prop
LawfulMonad
m: Type → Type u_1
m] :
(do'for
x: α
xin
xs: List α
xsdo' {
let
b: Bool
b←
p: α → m Bool
p
x: α
x;if
b: Bool
bthen {
break
}
})
=
xs: List α
xs.
untilM: {m : Type → Type u_1} → {α : Type} → [inst : Monad m] → (α → m Bool) → List α → m Unit
untilM
p: α → m Bool
p
:=
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool
ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =
List.untilM p xs
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool
ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =
List.untilM p xs
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs: List α act: α → m Unit p: α → m Bool
nil
ExceptCpsT.runCatch
(forM [] fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =
List.untilM p []
Goals accomplished!🐙
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =
List.untilM p xs
cons
ExceptCpsT.runCatch
(forM (x :: xs) fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =
List.untilM p (x :: xs)
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =
List.untilM p xs
cons
(dolet a ← p x
ExceptCpsT.runCatch doif a = true then throw () else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =dolet x ← p x
match x with| true => pure ()
| false => List.untilM p xs
;
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =
List.untilM p xs
cons
(dolet a ← p x
ExceptCpsT.runCatch doif a = true then throw () else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =dolet x ← p x
match x with| true => pure ()
| false => List.untilM p xs
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =
List.untilM p xs
cons
(dolet a ← p x
ExceptCpsT.runCatch doif a = true then throw () else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =dolet x ← p x
match x with| true => pure ()
| false =>
ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ()))
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α ih: ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =
List.untilM p xs
cons
(dolet a ← p x
ExceptCpsT.runCatch doif a = true then throw () else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =dolet x ← p x
match x with| true => pure ()
| false =>
ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ()))
;
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α
cons
(dolet a ← p x
ExceptCpsT.runCatch doif a = true then throw () else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =dolet x ← p x
match x with| true => pure ()
| false =>
ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ()))
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α
cons.isTrue
(ExceptCpsT.runCatch doif true = true then throw () else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =match true with| true => pure ()
| false =>
ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ()))
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α
(ExceptCpsT.runCatch doif false = true then throw () else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =match false with| true => pure ()
| false =>
ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ()))
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α
cons.isTrue
(ExceptCpsT.runCatch doif true = true then throw () else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =match true with| true => pure ()
| false =>
ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ()))
m: Type→Type u_1 α: Type inst✝¹: Monad m ma, ma': m α b: Bool xs✝: List α act: α → m Unit p: α → m Bool x: α xs: List α
(ExceptCpsT.runCatch doif false = true then throw () else ExceptCpsT.lift (pure ())
forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ())) =match false with| true => pure ()
| false =>
ExceptCpsT.runCatch
(forM xs fun x =>dolet b ← ExceptCpsT.lift (p x)
if b = true then throw () else ExceptCpsT.lift (pure ()))
Goals accomplished!🐙
/-The notation `[0:10]` is a range from 0 to 10 (exclusively).-/
s2)
/-Adding `repeat` and `while` statements-/-- The "partial" keyword allows users to define non-terminating functions in Lean.-- However, we currently cannot reason about them.@[specialize]partialdef
loopForever: [inst : Monad m] → (Unit → m Unit) → m Unit
loopForever [
Monad: (Type → Type u_1) → Type (max 1 u_1)
Monad
m: Type → Type u_1
m] (
f: Unit → m Unit
f :
Unit: Type
Unit→
m: Type → Type u_1
m
Unit: Type
Unit) :
m: Type → Type u_1
m
Unit: Type
Unit :=
f: Unit → m Unit
f
(): Unit
()*>
loopForever: [inst : Monad m] → (Unit → m Unit) → m Unit
loopForever
f: Unit → m Unit
f-- `Loop'` is a "helper" type. It is similar to `Unit`.-- Its `ForM` instance produces an "infinite" sequence of units.inductive
Loop': Type
Loop'where|
mk: Loop'
mk :
Loop': Type
Loop'
instance: {m : Type → Type u_1} → ForM m Loop' Unit
instance :
ForM: (Type → Type u_1) → Type → outParam Type → Type (max (max 1 u_1) 0)
ForM
m: Type → Type u_1
m
Loop': Type
Loop'
Unit: Type
Unitwhere
forM _
f: Unit → m PUnit
f :=
loopForever: {m : Type → Type u_1} → [inst : Monad m] → (Unit → m Unit) → m Unit