chore(frontends/lean): fun x, e ==> fun x => e
This commit is contained in:
parent
e29bf35d15
commit
a02443d23d
107 changed files with 1172 additions and 1166 deletions
|
|
@ -80,13 +80,13 @@ universes u₁ u₂ u₃
|
|||
/- Transitive closure for HasLift, HasCoe, HasCoeToFun -/
|
||||
|
||||
instance liftTrans {a : Sort u₁} {b : Sort u₂} {c : Sort u₃} [HasLift a b] [HasLiftT b c] : HasLiftT a c :=
|
||||
⟨λ x, liftT (lift x : b)⟩
|
||||
⟨fun x => liftT (lift x : b)⟩
|
||||
|
||||
instance liftRefl {a : Sort u} : HasLiftT a a :=
|
||||
⟨id⟩
|
||||
|
||||
instance coeTrans {a : Sort u₁} {b : Sort u₂} {c : Sort u₃} [HasCoe a b] [HasCoeT b c] : HasCoeT a c :=
|
||||
⟨λ x, coeT (coeB x : b)⟩
|
||||
⟨fun x => coeT (coeB x : b)⟩
|
||||
|
||||
instance coeBase {a : Sort u} {b : Sort v} [HasCoe a b] : HasCoeT a b :=
|
||||
⟨coeB⟩
|
||||
|
|
@ -106,7 +106,7 @@ instance coeBase {a : Sort u} {b : Sort v} [HasCoe a b] : HasCoeT a b :=
|
|||
...
|
||||
-/
|
||||
instance coeOption {a : Type u} : HasCoeT a (Option a) :=
|
||||
⟨λ x, some x⟩
|
||||
⟨fun x => some x⟩
|
||||
|
||||
/- Auxiliary transitive closure for HasCoe which does not contain
|
||||
instances such as coeOption.
|
||||
|
|
@ -117,18 +117,18 @@ class HasCoeTAux (a : Sort u) (b : Sort v) :=
|
|||
(coe : a → b)
|
||||
|
||||
instance coeTransAux {a : Sort u₁} {b : Sort u₂} {c : Sort u₃} [HasCoe a b] [HasCoeTAux b c] : HasCoeTAux a c :=
|
||||
⟨λ x : a, @HasCoeTAux.coe b c _ (coeB x)⟩
|
||||
⟨fun x : a => @HasCoeTAux.coe b c _ (coeB x)⟩
|
||||
|
||||
instance coeBaseAux {a : Sort u} {b : Sort v} [HasCoe a b] : HasCoeTAux a b :=
|
||||
⟨coeB⟩
|
||||
|
||||
instance coeFnTrans {a : Sort u₁} {b : Sort u₂} [HasCoeTAux a b] [HasCoeToFun.{u₂, u₃} b] : HasCoeToFun.{u₁, u₃} a :=
|
||||
{ F := λ x, @HasCoeToFun.F.{u₂, u₃} b _ (@HasCoeTAux.coe a b _ x),
|
||||
coe := λ x, coeFn (@HasCoeTAux.coe a b _ x) }
|
||||
{ F := fun x => @HasCoeToFun.F.{u₂, u₃} b _ (@HasCoeTAux.coe a b _ x),
|
||||
coe := fun x => coeFn (@HasCoeTAux.coe a b _ x) }
|
||||
|
||||
instance coeSortTrans {a : Sort u₁} {b : Sort u₂} [HasCoeTAux a b] [HasCoeToSort.{u₂, u₃} b] : HasCoeToSort.{u₁, u₃} a :=
|
||||
{ S := HasCoeToSort.S.{u₂, u₃} b,
|
||||
coe := λ x, coeSort (@HasCoeTAux.coe a b _ x) }
|
||||
coe := fun x => coeSort (@HasCoeTAux.coe a b _ x) }
|
||||
|
||||
/- Every coercion is also a lift -/
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ instance coeToLift {a : Sort u} {b : Sort v} [HasCoeT a b] : HasLiftT a b :=
|
|||
/- basic coercions -/
|
||||
|
||||
instance coeBoolToProp : HasCoe Bool Prop :=
|
||||
⟨λ y, y = true⟩
|
||||
⟨fun y => y = true⟩
|
||||
|
||||
/- Tactics such as the simplifier only unfold reducible constants when checking whether two terms are definitionally
|
||||
equal or a Term is a proposition. The motivation is performance.
|
||||
|
|
@ -146,7 +146,7 @@ instance coeBoolToProp : HasCoe Bool Prop :=
|
|||
Thus, we mark the following instance as @[reducible], otherwise `simp` will not visit `↑p` when simplifying `↑p -> q`.
|
||||
-/
|
||||
@[reducible] instance coeSortBool : HasCoeToSort Bool :=
|
||||
⟨Prop, λ y, y = true⟩
|
||||
⟨Prop, fun y => y = true⟩
|
||||
|
||||
instance coeDecidableEq (x : Bool) : Decidable (coe x) :=
|
||||
inferInstanceAs (Decidable (x = true))
|
||||
|
|
@ -161,22 +161,22 @@ universes ua ua₁ ua₂ ub ub₁ ub₂
|
|||
/- Remark: we can't use [HasLiftT a₂ a₁] since it will produce non-termination whenever a type class resolution
|
||||
problem does not have a solution. -/
|
||||
instance liftFn {a₁ : Sort ua₁} {a₂ : Sort ua₂} {b₁ : Sort ub₁} {b₂ : Sort ub₂} [HasLift a₂ a₁] [HasLiftT b₁ b₂] : HasLift (a₁ → b₁) (a₂ → b₂) :=
|
||||
⟨λ f x, coe (f (coe x))⟩
|
||||
⟨fun f x => coe (f (coe x))⟩
|
||||
|
||||
instance liftFnRange {a : Sort ua} {b₁ : Sort ub₁} {b₂ : Sort ub₂} [HasLiftT b₁ b₂] : HasLift (a → b₁) (a → b₂) :=
|
||||
⟨λ f x, coe (f x)⟩
|
||||
⟨fun f x => coe (f x)⟩
|
||||
|
||||
instance liftFnDom {a₁ : Sort ua₁} {a₂ : Sort ua₂} {b : Sort ub} [HasLift a₂ a₁] : HasLift (a₁ → b) (a₂ → b) :=
|
||||
⟨λ f x, f (coe x)⟩
|
||||
⟨fun f x => f (coe x)⟩
|
||||
|
||||
instance liftPair {a₁ : Type ua₁} {a₂ : Type ub₂} {b₁ : Type ub₁} {b₂ : Type ub₂} [HasLiftT a₁ a₂] [HasLiftT b₁ b₂] : HasLift (a₁ × b₁) (a₂ × b₂) :=
|
||||
⟨λ p, Prod.casesOn p (λ x y, (coe x, coe y))⟩
|
||||
⟨fun p => Prod.casesOn p (fun x y => (coe x, coe y))⟩
|
||||
|
||||
instance liftPair₁ {a₁ : Type ua₁} {a₂ : Type ua₂} {b : Type ub} [HasLiftT a₁ a₂] : HasLift (a₁ × b) (a₂ × b) :=
|
||||
⟨λ p, Prod.casesOn p (λ x y, (coe x, y))⟩
|
||||
⟨fun p => Prod.casesOn p (fun x y => (coe x, y))⟩
|
||||
|
||||
instance liftPair₂ {a : Type ua} {b₁ : Type ub₁} {b₂ : Type ub₂} [HasLiftT b₁ b₂] : HasLift (a × b₁) (a × b₂) :=
|
||||
⟨λ p, Prod.casesOn p (λ x y, (x, coe y))⟩
|
||||
⟨fun p => Prod.casesOn p (fun x y => (x, coe y))⟩
|
||||
|
||||
instance liftList {a : Type u} {b : Type v} [HasLiftT a b] : HasLift (List a) (List b) :=
|
||||
⟨λ l, List.map (@coe a b _) l⟩
|
||||
⟨fun l => List.map (@coe a b _) l⟩
|
||||
|
|
|
|||
|
|
@ -29,6 +29,6 @@ class HasSeqRight (f : Type u → Type v) : Type (max (u+1) v) :=
|
|||
infixr *> := HasSeqRight.seqRight
|
||||
|
||||
class Applicative (f : Type u → Type v) extends Functor f, HasPure f, HasSeq f, HasSeqLeft f, HasSeqRight f :=
|
||||
(map := λ _ _ x y, pure x <*> y)
|
||||
(seqLeft := λ α β a b, const β <$> a <*> b)
|
||||
(seqRight := λ α β a b, const α id <$> a <*> b)
|
||||
(map := fun _ _ x y => pure x <*> y)
|
||||
(seqLeft := fun α β a b => const β <$> a <*> b)
|
||||
(seqRight := fun α β a b => const α id <$> a <*> b)
|
||||
|
|
|
|||
|
|
@ -53,49 +53,49 @@ namespace EState
|
|||
variables {ε σ α β : Type u}
|
||||
|
||||
instance [Inhabited ε] : Inhabited (EState ε σ α) :=
|
||||
⟨λ r, match r with
|
||||
⟨fun r => match r with
|
||||
| ⟨Result.ok _ s, _⟩ := Result.error (default ε) s
|
||||
| ⟨Result.error _ _, h⟩ := unreachableError h⟩
|
||||
|
||||
@[inline] protected def pure (a : α) : EState ε σ α :=
|
||||
λ r, match r with
|
||||
fun r => match r with
|
||||
| ⟨Result.ok _ s, _⟩ := Result.ok a s
|
||||
| ⟨Result.error _ _, h⟩ := unreachableError h
|
||||
|
||||
@[inline] protected def set (s : σ) : EState ε σ PUnit :=
|
||||
λ r, match r with
|
||||
fun r => match r with
|
||||
| ⟨Result.ok _ _, _⟩ := Result.ok ⟨⟩ s
|
||||
| ⟨Result.error _ _, h⟩ := unreachableError h
|
||||
|
||||
@[inline] protected def get : EState ε σ σ :=
|
||||
λ r, match r with
|
||||
fun r => match r with
|
||||
| ⟨Result.ok _ s, _⟩ := Result.ok s s
|
||||
| ⟨Result.error _ _, h⟩ := unreachableError h
|
||||
|
||||
@[inline] protected def modify (f : σ → σ) : EState ε σ PUnit :=
|
||||
λ r, match r with
|
||||
fun r => match r with
|
||||
| ⟨Result.ok _ s, _⟩ := Result.ok ⟨⟩ (f s)
|
||||
| ⟨Result.error _ _, h⟩ := unreachableError h
|
||||
|
||||
@[inline] protected def throw (e : ε) : EState ε σ α :=
|
||||
λ r, match r with
|
||||
fun r => match r with
|
||||
| ⟨Result.ok _ s, _⟩ := Result.error e s
|
||||
| ⟨Result.error _ _, h⟩ := unreachableError h
|
||||
|
||||
@[inline] protected def catch (x : EState ε σ α) (handle : ε → EState ε σ α) : EState ε σ α :=
|
||||
λ r, match x r with
|
||||
fun r => match x r with
|
||||
| Result.error e s := handle e (resultOk.mk ⟨⟩ s)
|
||||
| ok := ok
|
||||
|
||||
@[inline] protected def orelse (x₁ x₂ : EState ε σ α) : EState ε σ α :=
|
||||
λ r, match x₁ r with
|
||||
fun r => match x₁ r with
|
||||
| Result.error _ s := x₂ (resultOk.mk ⟨⟩ s)
|
||||
| ok := ok
|
||||
|
||||
/-- Alternative orelse operator that allows to select which exception should be used.
|
||||
The default is to use the first exception since the standard `orelse` uses the second. -/
|
||||
@[inline] protected def orelse' (x₁ x₂ : EState ε σ α) (useFirstEx := true) : EState ε σ α :=
|
||||
λ r, match x₁ r with
|
||||
fun r => match x₁ r with
|
||||
| Result.error e₁ s₁ :=
|
||||
match x₂ (resultOk.mk ⟨⟩ s₁) with
|
||||
| Result.error e₂ s₂ := Result.error (if useFirstEx then e₁ else e₂) s₂
|
||||
|
|
@ -103,22 +103,22 @@ instance [Inhabited ε] : Inhabited (EState ε σ α) :=
|
|||
| ok := ok
|
||||
|
||||
@[inline] def adaptExcept {ε' : Type u} [HasLift ε ε'] (x : EState ε σ α) : EState ε' σ α :=
|
||||
λ r, match x r with
|
||||
fun r => match x r with
|
||||
| Result.error e s := Result.error (lift e) s
|
||||
| Result.ok a s := Result.ok a s
|
||||
|
||||
@[inline] protected def bind (x : EState ε σ α) (f : α → EState ε σ β) : EState ε σ β :=
|
||||
λ r, match x r with
|
||||
fun r => match x r with
|
||||
| Result.ok a s := f a (resultOk.mk ⟨⟩ s)
|
||||
| Result.error e s := Result.error e s
|
||||
|
||||
@[inline] protected def map (f : α → β) (x : EState ε σ α) : EState ε σ β :=
|
||||
λ r, match x r with
|
||||
fun r => match x r with
|
||||
| Result.ok a s := Result.ok (f a) s
|
||||
| Result.error e s := Result.error e s
|
||||
|
||||
@[inline] protected def seqRight (x : EState ε σ α) (y : EState ε σ β) : EState ε σ β :=
|
||||
λ r, match x r with
|
||||
fun r => match x r with
|
||||
| Result.ok _ s := y (resultOk.mk ⟨⟩ s)
|
||||
| Result.error e s := Result.error e s
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ ExceptT.mk $ pure (Except.ok a)
|
|||
ExceptT.mk $ ma >>= ExceptT.bindCont f
|
||||
|
||||
@[inline] protected def map {α β : Type u} (f : α → β) (x : ExceptT ε m α) : ExceptT ε m β :=
|
||||
ExceptT.mk $ x >>= λ a, match a with
|
||||
ExceptT.mk $ x >>= fun a => match a with
|
||||
| (Except.ok a) := pure $ Except.ok (f a)
|
||||
| (Except.error e) := pure $ Except.error e
|
||||
|
||||
|
|
@ -102,24 +102,24 @@ ExceptT.mk $ x >>= λ a, match a with
|
|||
ExceptT.mk $ Except.ok <$> t
|
||||
|
||||
instance exceptTOfExcept : HasMonadLift (Except ε) (ExceptT ε m) :=
|
||||
⟨λ α e, ExceptT.mk $ pure e⟩
|
||||
⟨fun α e => ExceptT.mk $ pure e⟩
|
||||
|
||||
instance : HasMonadLift m (ExceptT ε m) :=
|
||||
⟨@ExceptT.lift _ _ _⟩
|
||||
|
||||
@[inline] protected def catch {α : Type u} (ma : ExceptT ε m α) (handle : ε → ExceptT ε m α) : ExceptT ε m α :=
|
||||
ExceptT.mk $ ma >>= λ res, match res with
|
||||
ExceptT.mk $ ma >>= fun res => match res with
|
||||
| Except.ok a := pure (Except.ok a)
|
||||
| Except.error e := (handle e)
|
||||
|
||||
instance (m') [Monad m'] : MonadFunctor m m' (ExceptT ε m) (ExceptT ε m') :=
|
||||
⟨λ _ f x, f x⟩
|
||||
⟨fun _ f x => f x⟩
|
||||
|
||||
instance : Monad (ExceptT ε m) :=
|
||||
{ pure := @ExceptT.pure _ _ _, bind := @ExceptT.bind _ _ _, map := @ExceptT.map _ _ _ }
|
||||
|
||||
@[inline] protected def adapt {ε' α : Type u} (f : ε → ε') : ExceptT ε m α → ExceptT ε' m α :=
|
||||
λ x, ExceptT.mk $ Except.mapError f <$> x
|
||||
fun x => ExceptT.mk $ Except.mapError f <$> x
|
||||
end ExceptT
|
||||
|
||||
/-- An implementation of [MonadError](https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Except.html#t:MonadError) -/
|
||||
|
|
@ -131,12 +131,12 @@ namespace MonadExcept
|
|||
variables {ε : Type u} {m : Type v → Type w}
|
||||
|
||||
@[inline] protected def orelse [MonadExcept ε m] {α : Type v} (t₁ t₂ : m α) : m α :=
|
||||
catch t₁ $ λ _, t₂
|
||||
catch t₁ $ fun _ => t₂
|
||||
|
||||
/-- Alternative orelse operator that allows to select which exception should be used.
|
||||
The default is to use the first exception since the standard `orelse` uses the second. -/
|
||||
@[inline] def orelse' [MonadExcept ε m] {α : Type v} (t₁ t₂ : m α) (useFirstEx := true) : m α :=
|
||||
catch t₁ $ λ e₁, catch t₂ $ λ e₂, throw (if useFirstEx then e₁ else e₂)
|
||||
catch t₁ $ fun e₁ => catch t₂ $ fun e₂ => throw (if useFirstEx then e₁ else e₂)
|
||||
|
||||
@[inline] def liftExcept {ε' : Type u} [MonadExcept ε m] [HasLiftT ε' ε] [Monad m] {α : Type v} : Except ε' α → m α
|
||||
| (Except.error e) := throw (coe e)
|
||||
|
|
@ -146,11 +146,11 @@ end MonadExcept
|
|||
export MonadExcept (throw catch)
|
||||
|
||||
instance (m : Type u → Type v) (ε : Type u) [Monad m] : MonadExcept ε (ExceptT ε m) :=
|
||||
{ throw := λ α e, ExceptT.mk $ pure (Except.error e),
|
||||
{ throw := fun α e => ExceptT.mk $ pure (Except.error e),
|
||||
catch := @ExceptT.catch ε _ _ }
|
||||
|
||||
instance (ε) : MonadExcept ε (Except ε) :=
|
||||
{ throw := λ α, Except.error, catch := @Except.catch _ }
|
||||
{ throw := fun α => Except.error, catch := @Except.catch _ }
|
||||
|
||||
/-- Adapt a Monad stack, changing its top-most error Type.
|
||||
|
||||
|
|
@ -168,15 +168,15 @@ section
|
|||
variables {ε ε' : Type u} {m m' : Type u → Type v}
|
||||
|
||||
instance monadExceptAdapterTrans {n n' : Type u → Type v} [MonadFunctor m m' n n'] [MonadExceptAdapter ε ε' m m'] : MonadExceptAdapter ε ε' n n' :=
|
||||
⟨λ α f, monadMap (λ α, (adaptExcept f : m α → m' α))⟩
|
||||
⟨fun α f => monadMap (fun α => (adaptExcept f : m α → m' α))⟩
|
||||
|
||||
instance [Monad m] : MonadExceptAdapter ε ε' (ExceptT ε m) (ExceptT ε' m) :=
|
||||
⟨λ α, ExceptT.adapt⟩
|
||||
⟨fun α => ExceptT.adapt⟩
|
||||
end
|
||||
|
||||
instance (ε m out) [MonadRun out m] : MonadRun (λ α, out (Except ε α)) (ExceptT ε m) :=
|
||||
⟨λ α, run⟩
|
||||
instance (ε m out) [MonadRun out m] : MonadRun (fun α => out (Except ε α)) (ExceptT ε m) :=
|
||||
⟨fun α => run⟩
|
||||
|
||||
-- useful for implicit failures in do-notation
|
||||
instance (m : Type → Type) [Monad m] : MonadFail (ExceptT String m) :=
|
||||
⟨λ _, throw⟩
|
||||
⟨fun _ => throw⟩
|
||||
|
|
|
|||
|
|
@ -10,15 +10,15 @@ universes u v
|
|||
|
||||
class Functor (f : Type u → Type v) : Type (max (u+1) v) :=
|
||||
(map : Π {α β : Type u}, (α → β) → f α → f β)
|
||||
(mapConst : Π {α β : Type u}, α → f β → f α := λ α β, map ∘ const β)
|
||||
(mapConst : Π {α β : Type u}, α → f β → f α := fun α β => map ∘ const β)
|
||||
|
||||
infixr <$> := Functor.map
|
||||
infixr <$ := Functor.mapConst
|
||||
|
||||
@[reducible] def Functor.mapConstRev {f : Type u → Type v} [Functor f] {α β : Type u} : f β → α → f α :=
|
||||
λ a b, b <$ a
|
||||
fun a b => b <$ a
|
||||
infixr $> := Functor.mapConstRev
|
||||
|
||||
@[reducible] def Functor.mapRev {f : Type u → Type v} [Functor f] {α β : Type u} : f α → (α → β) → f β :=
|
||||
λ a f, f <$> a
|
||||
fun a f => f <$> a
|
||||
infixl <&> := Functor.mapRev
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@ export HasMonadLiftT (monadLift)
|
|||
⟨monadLift⟩
|
||||
|
||||
instance hasMonadLiftTTrans (m n o) [HasMonadLift n o] [HasMonadLiftT m n] : HasMonadLiftT m o :=
|
||||
⟨λ α ma, HasMonadLift.monadLift (monadLift ma : n α)⟩
|
||||
⟨fun α ma => HasMonadLift.monadLift (monadLift ma : n α)⟩
|
||||
|
||||
instance hasMonadLiftTRefl (m) : HasMonadLiftT m m :=
|
||||
⟨λ α, id⟩
|
||||
⟨fun α => id⟩
|
||||
|
||||
theorem monadLiftRefl {m : Type u → Type v} {α} : (monadLift : m α → m α) = id := rfl
|
||||
|
||||
|
|
@ -63,10 +63,10 @@ export MonadFunctorT (monadMap)
|
|||
|
||||
instance monadFunctorTTrans (m m' n n' o o') [MonadFunctor n n' o o'] [MonadFunctorT m m' n n'] :
|
||||
MonadFunctorT m m' o o' :=
|
||||
⟨λ α f, MonadFunctor.monadMap (λ β, (monadMap @f : n β → n' β))⟩
|
||||
⟨fun α f => MonadFunctor.monadMap (fun β => (monadMap @f : n β → n' β))⟩
|
||||
|
||||
instance monadFunctorTRefl (m m') : MonadFunctorT m m' m m' :=
|
||||
⟨λ α f, f⟩
|
||||
⟨fun α f => f⟩
|
||||
|
||||
theorem monadMapRefl {m m' : Type u → Type v} (f : ∀ {β}, m β → m' β) {α} : (monadMap @f : m α → m' α) = f := rfl
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,15 @@ export HasBind (bind)
|
|||
infixr >>= := bind
|
||||
|
||||
@[inline] def mcomp {α : Type u} {β δ : Type v} {m : Type v → Type w} [HasBind m] (f : α → m β) (g : β → m δ) : α → m δ :=
|
||||
λ a, f a >>= g
|
||||
fun a => f a >>= g
|
||||
|
||||
infixr >=> := mcomp
|
||||
|
||||
class Monad (m : Type u → Type v) extends Applicative m, HasBind m : Type (max (u+1) v) :=
|
||||
(map := λ α β f x, x >>= pure ∘ f)
|
||||
(seq := λ α β f x, f >>= (λ y, y <$> x))
|
||||
(seqLeft := λ α β x y, x >>= λ a, y >>= λ _, pure a)
|
||||
(seqRight := λ α β x y, x >>= λ _, y)
|
||||
(map := fun α β f x => x >>= pure ∘ f)
|
||||
(seq := fun α β f x => f >>= (fun y => y <$> x))
|
||||
(seqLeft := fun α β x y => x >>= fun a => y >>= fun _ => pure a)
|
||||
(seqRight := fun α β x y => x >>= fun _ => y)
|
||||
|
||||
instance monadInhabited' {α : Type u} {m : Type u → Type v} [Monad m] : Inhabited (α → m α) :=
|
||||
⟨pure⟩
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@ def matchFailed {α : Type u} {m : Type u → Type v} [MonadFail m] : m α :=
|
|||
MonadFail.fail "match failed"
|
||||
|
||||
instance monadFailLift (m n : Type u → Type v) [HasMonadLift m n] [MonadFail m] [Monad n] : MonadFail n :=
|
||||
{ fail := λ α s, monadLift (MonadFail.fail s : m α) }
|
||||
{ fail := fun α s => monadLift (MonadFail.fail s : m α) }
|
||||
|
|
|
|||
|
|
@ -49,18 +49,18 @@ namespace OptionT
|
|||
⟨@OptionT.lift _ _⟩
|
||||
|
||||
@[inline] protected def monadMap {m'} [Monad m'] {α} (f : ∀ {α}, m α → m' α) : OptionT m α → OptionT m' α :=
|
||||
λ x, f x
|
||||
fun x => f x
|
||||
|
||||
instance (m') [Monad m'] : MonadFunctor m m' (OptionT m) (OptionT m') :=
|
||||
⟨λ α, OptionT.monadMap⟩
|
||||
⟨fun α => OptionT.monadMap⟩
|
||||
|
||||
protected def catch (ma : OptionT m α) (handle : Unit → OptionT m α) : OptionT m α :=
|
||||
(do { some a ← ma | (handle ());
|
||||
pure a } : m (Option α))
|
||||
|
||||
instance : MonadExcept Unit (OptionT m) :=
|
||||
{ throw := λ _ _, OptionT.fail, catch := @OptionT.catch _ _ }
|
||||
{ throw := fun _ _ => OptionT.fail, catch := @OptionT.catch _ _ }
|
||||
|
||||
instance (m out) [MonadRun out m] : MonadRun (λ α, out (Option α)) (OptionT m) :=
|
||||
⟨λ α, MonadRun.run⟩
|
||||
instance (m out) [MonadRun out m] : MonadRun (fun α => out (Option α)) (OptionT m) :=
|
||||
⟨fun α => MonadRun.run⟩
|
||||
end OptionT
|
||||
|
|
|
|||
|
|
@ -27,34 +27,34 @@ variables {ρ : Type u} {m : Type u → Type v} [Monad m] {α β : Type u}
|
|||
pure
|
||||
|
||||
@[inline] protected def pure (a : α) : ReaderT ρ m α :=
|
||||
λ r, pure a
|
||||
fun r => pure a
|
||||
|
||||
@[inline] protected def bind (x : ReaderT ρ m α) (f : α → ReaderT ρ m β) : ReaderT ρ m β :=
|
||||
λ r, do a ← x r; f a r
|
||||
fun r => do a ← x r; f a r
|
||||
|
||||
@[inline] protected def map (f : α → β) (x : ReaderT ρ m α) : ReaderT ρ m β :=
|
||||
λ r, f <$> x r
|
||||
fun r => f <$> x r
|
||||
|
||||
instance : Monad (ReaderT ρ m) :=
|
||||
{ pure := @ReaderT.pure _ _ _, bind := @ReaderT.bind _ _ _, map := @ReaderT.map _ _ _ }
|
||||
|
||||
@[inline] protected def lift (a : m α) : ReaderT ρ m α :=
|
||||
λ r, a
|
||||
fun r => a
|
||||
|
||||
instance (m) [Monad m] : HasMonadLift m (ReaderT ρ m) :=
|
||||
⟨@ReaderT.lift ρ m _⟩
|
||||
|
||||
instance (ρ m m') [Monad m] [Monad m'] : MonadFunctor m m' (ReaderT ρ m) (ReaderT ρ m') :=
|
||||
⟨λ _ f x, λ r, f (x r)⟩
|
||||
⟨fun _ f x r => f (x r)⟩
|
||||
|
||||
@[inline] protected def adapt {ρ' : Type u} [Monad m] {α : Type u} (f : ρ' → ρ) : ReaderT ρ m α → ReaderT ρ' m α :=
|
||||
λ x r, x (f r)
|
||||
fun x r => x (f r)
|
||||
|
||||
@[inline] protected def orelse [Alternative m] {α : Type u} (x₁ x₂ : ReaderT ρ m α) : ReaderT ρ m α :=
|
||||
λ s, x₁ s <|> x₂ s
|
||||
fun s => x₁ s <|> x₂ s
|
||||
|
||||
@[inline] protected def failure [Alternative m] {α : Type u} : ReaderT ρ m α :=
|
||||
λ s, failure
|
||||
fun s => failure
|
||||
|
||||
instance [Alternative m] : Alternative (ReaderT ρ m) :=
|
||||
{ failure := @ReaderT.failure _ _ _ _,
|
||||
|
|
@ -62,8 +62,8 @@ instance [Alternative m] : Alternative (ReaderT ρ m) :=
|
|||
..ReaderT.Monad }
|
||||
|
||||
instance (ε) [Monad m] [MonadExcept ε m] : MonadExcept ε (ReaderT ρ m) :=
|
||||
{ throw := λ α, ReaderT.lift ∘ throw,
|
||||
catch := λ α x c r, catch (x r) (λ e, (c e) r) }
|
||||
{ throw := fun α => ReaderT.lift ∘ throw,
|
||||
catch := fun α x c r => catch (x r) (fun e => (c e) r) }
|
||||
end
|
||||
end ReaderT
|
||||
|
||||
|
|
@ -108,14 +108,14 @@ section
|
|||
variables {ρ ρ' : Type u} {m m' : Type u → Type v}
|
||||
|
||||
instance monadReaderAdapterTrans {n n' : Type u → Type v} [MonadFunctor m m' n n'] [MonadReaderAdapter ρ ρ' m m'] : MonadReaderAdapter ρ ρ' n n' :=
|
||||
⟨λ α f, monadMap (λ α, (adaptReader f : m α → m' α))⟩
|
||||
⟨fun α f => monadMap (fun α => (adaptReader f : m α → m' α))⟩
|
||||
|
||||
instance [Monad m] : MonadReaderAdapter ρ ρ' (ReaderT ρ m) (ReaderT ρ' m) :=
|
||||
⟨λ α, ReaderT.adapt⟩
|
||||
⟨fun α => ReaderT.adapt⟩
|
||||
end
|
||||
|
||||
instance (ρ : Type u) (m out) [MonadRun out m] : MonadRun (λ α, ρ → out α) (ReaderT ρ m) :=
|
||||
⟨λ α x, run ∘ x⟩
|
||||
instance (ρ : Type u) (m out) [MonadRun out m] : MonadRun (fun α => ρ → out α) (ReaderT ρ m) :=
|
||||
⟨fun α x => run ∘ x⟩
|
||||
|
||||
class MonadReaderRunner (ρ : Type u) (m m' : Type u → Type u) :=
|
||||
(runReader {} {α : Type u} : m α → ρ → m' α)
|
||||
|
|
@ -125,8 +125,8 @@ section
|
|||
variables {ρ ρ' : Type u} {m m' : Type u → Type u}
|
||||
|
||||
instance monadReaderRunnerTrans {n n' : Type u → Type u} [MonadFunctor m m' n n'] [MonadReaderRunner ρ m m'] : MonadReaderRunner ρ n n' :=
|
||||
⟨λ α x r, monadMap (λ α (y : m α), (runReader y r : m' α)) x⟩
|
||||
⟨fun α x r => monadMap (fun (α) (y : m α) => (runReader y r : m' α)) x⟩
|
||||
|
||||
instance ReaderT.MonadStateRunner [Monad m] : MonadReaderRunner ρ (ReaderT ρ m) m :=
|
||||
⟨λ α x r, x r⟩
|
||||
⟨fun α x r => x r⟩
|
||||
end
|
||||
|
|
|
|||
|
|
@ -27,22 +27,22 @@ variables {σ : Type u} {m : Type u → Type v}
|
|||
variables [Monad m] {α β : Type u}
|
||||
|
||||
@[inline] protected def pure (a : α) : StateT σ m α :=
|
||||
λ s, pure (a, s)
|
||||
fun s => pure (a, s)
|
||||
|
||||
@[inline] protected def bind (x : StateT σ m α) (f : α → StateT σ m β) : StateT σ m β :=
|
||||
λ s, do (a, s) ← x s; f a s
|
||||
fun s => do (a, s) ← x s; f a s
|
||||
|
||||
@[inline] protected def map (f : α → β) (x : StateT σ m α) : StateT σ m β :=
|
||||
λ s, do (a, s) ← x s; pure (f a, s)
|
||||
fun s => do (a, s) ← x s; pure (f a, s)
|
||||
|
||||
instance : Monad (StateT σ m) :=
|
||||
{ pure := @StateT.pure _ _ _, bind := @StateT.bind _ _ _, map := @StateT.map _ _ _ }
|
||||
|
||||
@[inline] protected def orelse [Alternative m] {α : Type u} (x₁ x₂ : StateT σ m α) : StateT σ m α :=
|
||||
λ s, x₁ s <|> x₂ s
|
||||
fun s => x₁ s <|> x₂ s
|
||||
|
||||
@[inline] protected def failure [Alternative m] {α : Type u} : StateT σ m α :=
|
||||
λ s, failure
|
||||
fun s => failure
|
||||
|
||||
instance [Alternative m] : Alternative (StateT σ m) :=
|
||||
{ failure := @StateT.failure _ _ _ _,
|
||||
|
|
@ -50,33 +50,33 @@ instance [Alternative m] : Alternative (StateT σ m) :=
|
|||
.. StateT.Monad }
|
||||
|
||||
@[inline] protected def get : StateT σ m σ :=
|
||||
λ s, pure (s, s)
|
||||
fun s => pure (s, s)
|
||||
|
||||
@[inline] protected def set : σ → StateT σ m PUnit :=
|
||||
λ s' s, pure (⟨⟩, s')
|
||||
fun s' s => pure (⟨⟩, s')
|
||||
|
||||
@[inline] protected def modify (f : σ → σ) : StateT σ m PUnit :=
|
||||
λ s, pure (⟨⟩, f s)
|
||||
fun s => pure (⟨⟩, f s)
|
||||
|
||||
@[inline] protected def lift {α : Type u} (t : m α) : StateT σ m α :=
|
||||
λ s, do a ← t; pure (a, s)
|
||||
fun s => do a ← t; pure (a, s)
|
||||
|
||||
instance : HasMonadLift m (StateT σ m) :=
|
||||
⟨@StateT.lift σ m _⟩
|
||||
|
||||
instance (σ m m') [Monad m] [Monad m'] : MonadFunctor m m' (StateT σ m) (StateT σ m') :=
|
||||
⟨λ _ f x s, f (x s)⟩
|
||||
⟨fun _ f x s => f (x s)⟩
|
||||
|
||||
@[inline] protected def adapt {σ σ' σ'' α : Type u} {m : Type u → Type v} [Monad m] (split : σ → σ' × σ'')
|
||||
(join : σ' → σ'' → σ) (x : StateT σ' m α) : StateT σ m α :=
|
||||
λ st, do
|
||||
fun st => do
|
||||
let (st, ctx) := split st;
|
||||
(a, st') ← x st;
|
||||
pure (a, join st' ctx)
|
||||
|
||||
instance (ε) [MonadExcept ε m] : MonadExcept ε (StateT σ m) :=
|
||||
{ throw := λ α, StateT.lift ∘ throw,
|
||||
catch := λ α x c s, catch (x s) (λ e, c e s) }
|
||||
{ throw := fun α => StateT.lift ∘ throw,
|
||||
catch := fun α x c s => catch (x s) (fun e => c e s) }
|
||||
end
|
||||
end StateT
|
||||
|
||||
|
|
@ -106,8 +106,8 @@ do s ← get; modify f; pure s
|
|||
-- will be picked first
|
||||
instance monadStateTrans {n : Type u → Type w} [HasMonadLift m n] [MonadState σ m] : MonadState σ n :=
|
||||
{ get := monadLift (MonadState.get : m _),
|
||||
set := λ st, monadLift (MonadState.set st : m _),
|
||||
modify := λ f, monadLift (MonadState.modify f : m _) }
|
||||
set := fun st => monadLift (MonadState.set st : m _),
|
||||
modify := fun f => monadLift (MonadState.modify f : m _) }
|
||||
|
||||
instance [Monad m] : MonadState σ (StateT σ m) :=
|
||||
{ get := StateT.get,
|
||||
|
|
@ -133,7 +133,7 @@ end
|
|||
Example:
|
||||
```
|
||||
def withSnd {α σ σ' : Type} (snd : σ') : State (σ × σ') α → State σ α :=
|
||||
adaptState (λ st, ((st, snd), ())) (λ ⟨st,snd⟩ _, st)
|
||||
adaptState (fun st => ((st, snd), ())) (fun ⟨st,snd⟩ _ => st)
|
||||
```
|
||||
|
||||
Note: This class can be seen as a simplification of the more "principled" definition
|
||||
|
|
@ -142,10 +142,10 @@ end
|
|||
(map {} {α : Type u} : (∀ {m : Type u → Type u} [Monad m], StateT σ m α → StateT σ' m α) → n α → n' α)
|
||||
```
|
||||
which better describes the intent of "we can map a `StateT` anywhere in the Monad stack".
|
||||
If we look at the unfolded Type of the first argument `∀ m [Monad m], (σ → m (α × σ)) → σ' → m (α × σ')`, we see that it has the lens Type `∀ f [Functor f], (α → f α) → β → f β` with `f` specialized to `λ σ, m (α × σ)` (exercise: show that this is a lawful Functor). We can build all lenses we are insterested in from the functions `split` and `join` as
|
||||
If we look at the unfolded Type of the first argument `∀ m [Monad m], (σ → m (α × σ)) → σ' → m (α × σ')`, we see that it has the lens Type `∀ f [Functor f], (α → f α) → β → f β` with `f` specialized to `fun σ => m (α × σ)` (exercise: show that this is a lawful Functor). We can build all lenses we are insterested in from the functions `split` and `join` as
|
||||
```
|
||||
λ f _ st, let (st, ctx) := split st in
|
||||
(λ st', join st' ctx) <$> f st
|
||||
fun f _ st => let (st, ctx) := split st in
|
||||
(fun st' => join st' ctx) <$> f st
|
||||
```
|
||||
-/
|
||||
class MonadStateAdapter (σ σ' : outParam (Type u)) (m m' : Type u → Type v) :=
|
||||
|
|
@ -156,18 +156,18 @@ section
|
|||
variables {σ σ' : Type u} {m m' : Type u → Type v}
|
||||
|
||||
def MonadStateAdapter.adaptState' [MonadStateAdapter σ σ' m m'] {α : Type u} (toSigma : σ' → σ) (fromSigma : σ → σ') : m α → m' α :=
|
||||
adaptState (λ st, (toSigma st, PUnit.unit)) (λ st _, fromSigma st)
|
||||
adaptState (fun st => (toSigma st, PUnit.unit)) (fun st _ => fromSigma st)
|
||||
export MonadStateAdapter (adaptState')
|
||||
|
||||
instance monadStateAdapterTrans {n n' : Type u → Type v} [MonadFunctor m m' n n'] [MonadStateAdapter σ σ' m m'] : MonadStateAdapter σ σ' n n' :=
|
||||
⟨λ σ'' α split join, monadMap (λ α, (adaptState split join : m α → m' α))⟩
|
||||
⟨fun σ'' α split join => monadMap (fun α => (adaptState split join : m α → m' α))⟩
|
||||
|
||||
instance [Monad m] : MonadStateAdapter σ σ' (StateT σ m) (StateT σ' m) :=
|
||||
⟨λ σ'' α, StateT.adapt⟩
|
||||
⟨fun σ'' α => StateT.adapt⟩
|
||||
end
|
||||
|
||||
instance (σ : Type u) (m out : Type u → Type v) [Functor m] [MonadRun out m] : MonadRun (λ α, σ → out α) (StateT σ m) :=
|
||||
⟨λ α x, run ∘ StateT.run' x⟩
|
||||
instance (σ : Type u) (m out : Type u → Type v) [Functor m] [MonadRun out m] : MonadRun (fun α => σ → out α) (StateT σ m) :=
|
||||
⟨fun α x => run ∘ StateT.run' x⟩
|
||||
|
||||
class MonadStateRunner (σ : Type u) (m m' : Type u → Type u) :=
|
||||
(runState {} {α : Type u} : m α → σ → m' α)
|
||||
|
|
@ -177,8 +177,8 @@ section
|
|||
variables {σ σ' : Type u} {m m' : Type u → Type u}
|
||||
|
||||
instance monadStateRunnerTrans {n n' : Type u → Type u} [MonadFunctor m m' n n'] [MonadStateRunner σ m m'] : MonadStateRunner σ n n' :=
|
||||
⟨λ α x s, monadMap (λ α (y : m α), (runState y s : m' α)) x⟩
|
||||
⟨fun α x s => monadMap (fun (α) (y : m α) => (runState y s : m' α)) x⟩
|
||||
|
||||
instance StateT.MonadStateRunner [Monad m] : MonadStateRunner σ (StateT σ m) m :=
|
||||
⟨λ α x s, Prod.fst <$> x s⟩
|
||||
⟨fun α x s => Prod.fst <$> x s⟩
|
||||
end
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ unsafe axiom lcUnreachable {α : Sort u} : α
|
|||
def inline {α : Sort u} (a : α) : α := a
|
||||
|
||||
@[inline] def flip {α : Sort u} {β : Sort v} {φ : Sort w} (f : α → β → φ) : β → α → φ :=
|
||||
λ b a, f a b
|
||||
fun b a => f a b
|
||||
|
||||
/-
|
||||
The kernel definitional equality test (t =?= s) has special support for idDelta applications.
|
||||
|
|
@ -159,16 +159,16 @@ attribute [extern cpp inline "lean::mk_thunk(#2)"] Thunk.mk
|
|||
|
||||
@[noinline, extern cpp inline "lean::thunk_pure(#2)"]
|
||||
protected def Thunk.pure {α : Type u} (a : α) : Thunk α :=
|
||||
⟨λ _, a⟩
|
||||
⟨fun _ => a⟩
|
||||
@[noinline, extern cpp inline "lean::thunk_get_own(#2)"]
|
||||
protected def Thunk.get {α : Type u} (x : @& Thunk α) : α :=
|
||||
x.fn ()
|
||||
@[noinline, extern cpp inline "lean::thunk_map(#3, #4)"]
|
||||
protected def Thunk.map {α : Type u} {β : Type v} (f : α → β) (x : Thunk α) : Thunk β :=
|
||||
⟨λ _, f x.get⟩
|
||||
⟨fun _ => f x.get⟩
|
||||
@[noinline, extern cpp inline "lean::thunk_bind(#3, #4)"]
|
||||
protected def Thunk.bind {α : Type u} {β : Type v} (x : Thunk α) (f : α → Thunk β) : Thunk β :=
|
||||
⟨λ _, (f x.get).get⟩
|
||||
⟨fun _ => (f x.get).get⟩
|
||||
|
||||
/- Remark: tasks have an efficient implementation in the runtime. -/
|
||||
structure Task (α : Type u) : Type u :=
|
||||
|
|
@ -178,16 +178,16 @@ attribute [extern cpp inline "lean::mk_task(#2)"] Task.mk
|
|||
|
||||
@[noinline, extern cpp inline "lean::task_pure(#2)"]
|
||||
protected def Task.pure {α : Type u} (a : α) : Task α :=
|
||||
⟨λ _, a⟩
|
||||
⟨fun _ => a⟩
|
||||
@[noinline, extern cpp inline "lean::task_get(#2)"]
|
||||
protected def Task.get {α : Type u} (x : @& Task α) : α :=
|
||||
x.fn ()
|
||||
@[noinline, extern cpp inline "lean::task_map(#3, #4)"]
|
||||
protected def Task.map {α : Type u} {β : Type v} (f : α → β) (x : Task α) : Task β :=
|
||||
⟨λ _, f x.get⟩
|
||||
⟨fun _ => f x.get⟩
|
||||
@[noinline, extern cpp inline "lean::task_bind(#3, #4)"]
|
||||
protected def Task.bind {α : Type u} {β : Type v} (x : Task α) (f : α → Task β) : Task β :=
|
||||
⟨λ _, (f x.get).get⟩
|
||||
⟨fun _ => (f x.get).get⟩
|
||||
|
||||
inductive True : Prop
|
||||
| intro : True
|
||||
|
|
@ -204,11 +204,11 @@ inductive Eq {α : Sort u} (a : α) : α → Prop
|
|||
|
||||
@[elabAsEliminator, inline, reducible]
|
||||
def Eq.ndrec.{u1, u2} {α : Sort u2} {a : α} {C : α → Sort u1} (m : C a) {b : α} (h : Eq a b) : C b :=
|
||||
@Eq.rec α a (λ α _, C α) m b h
|
||||
@Eq.rec α a (fun α _ => C α) m b h
|
||||
|
||||
@[elabAsEliminator, inline, reducible]
|
||||
def Eq.ndrecOn.{u1, u2} {α : Sort u2} {a : α} {C : α → Sort u1} {b : α} (h : Eq a b) (m : C a) : C b :=
|
||||
@Eq.rec α a (λ α _, C α) m b h
|
||||
@Eq.rec α a (fun α _ => C α) m b h
|
||||
|
||||
/-
|
||||
Initialize the Quotient Module, which effectively adds the following definitions:
|
||||
|
|
@ -267,7 +267,7 @@ infix ≅ := Heq
|
|||
|
||||
theorem eqOfHeq {α : Sort u} {a a' : α} (h : a ≅ a') : a = a' :=
|
||||
have ∀ (α' : Sort u) (a' : α') (h₁ : @Heq α a α' a') (h₂ : α = α'), (Eq.recOn h₂ a : α') = a', from
|
||||
λ (α' : Sort u) (a' : α') (h₁ : @Heq α a α' a'), Heq.recOn h₁ (λ h₂ : α = α, rfl),
|
||||
fun (α' : Sort u) (a' : α') (h₁ : @Heq α a α' a') => Heq.recOn h₁ (fun h₂ : α = α => rfl),
|
||||
show (Eq.ndrecOn (Eq.refl α) a : α) = a', from
|
||||
this α a' h (Eq.refl α)
|
||||
|
||||
|
|
@ -631,17 +631,18 @@ infix != := bne
|
|||
def implies (a b : Prop) := a → b
|
||||
|
||||
theorem implies.trans {p q r : Prop} (h₁ : implies p q) (h₂ : implies q r) : implies p r :=
|
||||
λ hp, h₂ (h₁ hp)
|
||||
fun hp => h₂ (h₁ hp)
|
||||
|
||||
def trivial : True := ⟨⟩
|
||||
|
||||
@[macroInline] def False.elim {C : Sort u} (h : False) : C :=
|
||||
False.rec (λ _, C) h
|
||||
False.rec (fun _ => C) h
|
||||
|
||||
@[macroInline] def absurd {a : Prop} {b : Sort v} (h₁ : a) (h₂ : ¬a) : b :=
|
||||
False.elim (h₂ h₁)
|
||||
|
||||
theorem mt {a b : Prop} (h₁ : a → b) (h₂ : ¬b) : ¬a := λ ha : a, h₂ (h₁ ha)
|
||||
theorem mt {a b : Prop} (h₁ : a → b) (h₂ : ¬b) : ¬a :=
|
||||
fun ha => h₂ (h₁ ha)
|
||||
|
||||
theorem notFalse : ¬False := id
|
||||
|
||||
|
|
@ -654,7 +655,7 @@ theorem id.def {α : Sort u} (a : α) : id a = a := rfl
|
|||
Eq.recOn h₁ h₂
|
||||
|
||||
@[macroInline] def Eq.mpr {α β : Sort u} : (α = β) → β → α :=
|
||||
λ h₁ h₂, Eq.recOn (Eq.symm h₁) h₂
|
||||
fun h₁ h₂ => Eq.recOn (Eq.symm h₁) h₂
|
||||
|
||||
@[elabAsEliminator]
|
||||
theorem Eq.substr {α : Sort u} {p : α → Prop} {a b : α} (h₁ : b = a) (h₂ : p a) : p b :=
|
||||
|
|
@ -679,7 +680,7 @@ theorem ofEqTrue {p : Prop} (h : p = True) : p :=
|
|||
h.symm ▸ trivial
|
||||
|
||||
theorem notOfEqFalse {p : Prop} (h : p = False) : ¬p :=
|
||||
λ hp, h ▸ hp
|
||||
fun hp => h ▸ hp
|
||||
|
||||
@[macroInline] def cast {α β : Sort u} (h : α = β) (a : α) : β :=
|
||||
Eq.rec a h
|
||||
|
|
@ -704,15 +705,15 @@ theorem Ne.elim (h : a ≠ b) : a = b → False := h
|
|||
theorem Ne.irrefl (h : a ≠ a) : False := h rfl
|
||||
|
||||
theorem Ne.symm (h : a ≠ b) : b ≠ a :=
|
||||
λ (h₁ : b = a), h (h₁.symm)
|
||||
fun h₁ => h (h₁.symm)
|
||||
|
||||
theorem falseOfNe : a ≠ a → False := Ne.irrefl
|
||||
|
||||
theorem neFalseOfSelf : p → p ≠ False :=
|
||||
λ (hp : p) (Heq : p = False), Heq ▸ hp
|
||||
fun (hp : p) (Heq : p = False) => Heq ▸ hp
|
||||
|
||||
theorem neTrueOfNot : ¬p → p ≠ True :=
|
||||
λ (hnp : ¬p) (Heq : p = True), (Heq ▸ hnp) trivial
|
||||
fun (hnp : ¬p) (Heq : p = True) => (Heq ▸ hnp) trivial
|
||||
|
||||
theorem trueNeFalse : ¬True = False :=
|
||||
neFalseOfSelf trivial
|
||||
|
|
@ -731,11 +732,11 @@ variables {α β φ : Sort u} {a a' : α} {b b' : β} {c : φ}
|
|||
|
||||
@[elabAsEliminator]
|
||||
theorem Heq.ndrec.{u1, u2} {α : Sort u2} {a : α} {C : Π {β : Sort u2}, β → Sort u1} (m : C a) {β : Sort u2} {b : β} (h : a ≅ b) : C b :=
|
||||
@Heq.rec α a (λ β b _, C b) m β b h
|
||||
@Heq.rec α a (fun β b _ => C b) m β b h
|
||||
|
||||
@[elabAsEliminator]
|
||||
theorem Heq.ndrecOn.{u1, u2} {α : Sort u2} {a : α} {C : Π {β : Sort u2}, β → Sort u1} {β : Sort u2} {b : β} (h : a ≅ b) (m : C a) : C b :=
|
||||
@Heq.rec α a (λ β b _, C b) m β b h
|
||||
@Heq.rec α a (fun β b _ => C b) m β b h
|
||||
|
||||
theorem Heq.elim {α : Sort u} {a : α} {p : α → Sort v} {b : α} (h₁ : a ≅ b) (h₂ : p a) : p b :=
|
||||
Eq.recOn (eqOfHeq h₁) h₂
|
||||
|
|
@ -777,7 +778,7 @@ theorem And.elim (h₁ : a ∧ b) (h₂ : a → b → c) : c :=
|
|||
And.rec h₂ h₁
|
||||
|
||||
theorem And.swap : a ∧ b → b ∧ a :=
|
||||
λ ⟨ha, hb⟩, ⟨hb, ha⟩
|
||||
fun ⟨ha, hb⟩ => ⟨hb, ha⟩
|
||||
|
||||
def And.symm := @And.swap
|
||||
|
||||
|
|
@ -800,18 +801,18 @@ theorem Iff.left : (a ↔ b) → a → b := Iff.mp
|
|||
theorem Iff.right : (a ↔ b) → b → a := Iff.mpr
|
||||
|
||||
theorem iffIffImpliesAndImplies (a b : Prop) : (a ↔ b) ↔ (a → b) ∧ (b → a) :=
|
||||
Iff.intro (λ h, And.intro h.mp h.mpr) (λ h, Iff.intro h.left h.right)
|
||||
Iff.intro (fun h => And.intro h.mp h.mpr) (fun h => Iff.intro h.left h.right)
|
||||
|
||||
theorem Iff.refl (a : Prop) : a ↔ a :=
|
||||
Iff.intro (λ h, h) (λ h, h)
|
||||
Iff.intro (fun h => h) (fun h => h)
|
||||
|
||||
theorem Iff.rfl {a : Prop} : a ↔ a :=
|
||||
Iff.refl a
|
||||
|
||||
theorem Iff.trans (h₁ : a ↔ b) (h₂ : b ↔ c) : a ↔ c :=
|
||||
Iff.intro
|
||||
(λ ha, Iff.mp h₂ (Iff.mp h₁ ha))
|
||||
(λ hc, Iff.mpr h₁ (Iff.mpr h₂ hc))
|
||||
(fun ha => Iff.mp h₂ (Iff.mp h₁ ha))
|
||||
(fun hc => Iff.mpr h₁ (Iff.mpr h₂ hc))
|
||||
|
||||
theorem Iff.symm (h : a ↔ b) : b ↔ a :=
|
||||
Iff.intro (Iff.right h) (Iff.left h)
|
||||
|
|
@ -823,14 +824,14 @@ theorem Eq.toIff {a b : Prop} (h : a = b) : a ↔ b :=
|
|||
Eq.recOn h Iff.rfl
|
||||
|
||||
theorem neqOfNotIff {a b : Prop} : ¬(a ↔ b) → a ≠ b :=
|
||||
λ h₁ h₂,
|
||||
fun h₁ h₂ =>
|
||||
have a ↔ b, from Eq.subst h₂ (Iff.refl a),
|
||||
absurd this h₁
|
||||
|
||||
theorem notIffNotOfIff (h₁ : a ↔ b) : ¬a ↔ ¬b :=
|
||||
Iff.intro
|
||||
(λ (hna : ¬ a) (hb : b), hna (Iff.right h₁ hb))
|
||||
(λ (hnb : ¬ b) (ha : a), hnb (Iff.left h₁ ha))
|
||||
(fun (hna : ¬ a) (hb : b) => hna (Iff.right h₁ hb))
|
||||
(fun (hnb : ¬ b) (ha : a) => hnb (Iff.left h₁ ha))
|
||||
|
||||
theorem ofIffTrue (h : a ↔ True) : a :=
|
||||
Iff.mp (Iff.symm h) trivial
|
||||
|
|
@ -839,14 +840,14 @@ theorem notOfIffFalse : (a ↔ False) → ¬a := Iff.mp
|
|||
|
||||
theorem iffTrueIntro (h : a) : a ↔ True :=
|
||||
Iff.intro
|
||||
(λ hl, trivial)
|
||||
(λ hr, h)
|
||||
(fun hl => trivial)
|
||||
(fun hr => h)
|
||||
|
||||
theorem iffFalseIntro (h : ¬a) : a ↔ False :=
|
||||
Iff.intro h (False.rec (λ _, a))
|
||||
Iff.intro h (False.rec (fun _ => a))
|
||||
|
||||
theorem notNotIntro (ha : a) : ¬¬a :=
|
||||
λ hna : ¬a, hna ha
|
||||
fun hna => hna ha
|
||||
|
||||
theorem notTrue : (¬ True) ↔ False :=
|
||||
iffFalseIntro (notNotIntro trivial)
|
||||
|
|
@ -854,38 +855,38 @@ iffFalseIntro (notNotIntro trivial)
|
|||
/- or resolution rulses -/
|
||||
|
||||
theorem resolveLeft {a b : Prop} (h : a ∨ b) (na : ¬ a) : b :=
|
||||
Or.elim h (λ ha, absurd ha na) id
|
||||
Or.elim h (fun ha => absurd ha na) id
|
||||
|
||||
theorem negResolveLeft {a b : Prop} (h : ¬ a ∨ b) (ha : a) : b :=
|
||||
Or.elim h (λ na, absurd ha na) id
|
||||
Or.elim h (fun na => absurd ha na) id
|
||||
|
||||
theorem resolveRight {a b : Prop} (h : a ∨ b) (nb : ¬ b) : a :=
|
||||
Or.elim h id (λ hb, absurd hb nb)
|
||||
Or.elim h id (fun hb => absurd hb nb)
|
||||
|
||||
theorem negResolveRight {a b : Prop} (h : a ∨ ¬ b) (hb : b) : a :=
|
||||
Or.elim h id (λ nb, absurd hb nb)
|
||||
Or.elim h id (fun nb => absurd hb nb)
|
||||
|
||||
/- Exists -/
|
||||
|
||||
theorem Exists.elim {α : Sort u} {p : α → Prop} {b : Prop}
|
||||
(h₁ : Exists (λ x, p x)) (h₂ : ∀ (a : α), p a → b) : b :=
|
||||
(h₁ : Exists (fun x => p x)) (h₂ : ∀ (a : α), p a → b) : b :=
|
||||
Exists.rec h₂ h₁
|
||||
|
||||
/- Decidable -/
|
||||
|
||||
@[inlineIfReduce, nospecialize] def Decidable.decide (p : Prop) [h : Decidable p] : Bool :=
|
||||
Decidable.casesOn h (λ h₁, false) (λ h₂, true)
|
||||
Decidable.casesOn h (fun h₁ => false) (fun h₂ => true)
|
||||
|
||||
export Decidable (isTrue isFalse decide)
|
||||
|
||||
instance beqOfEq {α : Type u} [DecidableEq α] : HasBeq α :=
|
||||
⟨λ a b, decide (a = b)⟩
|
||||
⟨fun a b => decide (a = b)⟩
|
||||
|
||||
theorem decideTrueEqTrue (h : Decidable True) : @decide True h = true :=
|
||||
Decidable.casesOn h (λ h, False.elim (Iff.mp notTrue h)) (λ _, rfl)
|
||||
Decidable.casesOn h (fun h => False.elim (Iff.mp notTrue h)) (fun _ => rfl)
|
||||
|
||||
theorem decideFalseEqFalse (h : Decidable False) : @decide False h = false :=
|
||||
Decidable.casesOn h (λ h, rfl) (λ h, False.elim h)
|
||||
Decidable.casesOn h (fun h => rfl) (fun h => False.elim h)
|
||||
|
||||
instance : Decidable True :=
|
||||
isTrue trivial
|
||||
|
|
@ -896,23 +897,23 @@ isFalse notFalse
|
|||
-- We use "dependent" if-then-else to be able to communicate the if-then-else condition
|
||||
-- to the branches
|
||||
@[macroInline] def dite (c : Prop) [h : Decidable c] {α : Sort u} : (c → α) → (¬ c → α) → α :=
|
||||
λ t e, Decidable.casesOn h e t
|
||||
fun t e => Decidable.casesOn h e t
|
||||
|
||||
/- if-then-else -/
|
||||
|
||||
@[macroInline] def ite (c : Prop) [h : Decidable c] {α : Sort u} (t e : α) : α :=
|
||||
Decidable.casesOn h (λ hnc, e) (λ hc, t)
|
||||
Decidable.casesOn h (fun hnc => e) (fun hc => t)
|
||||
|
||||
namespace Decidable
|
||||
variables {p q : Prop}
|
||||
|
||||
def recOnTrue [h : Decidable p] {h₁ : p → Sort u} {h₂ : ¬p → Sort u} (h₃ : p) (h₄ : h₁ h₃)
|
||||
: (Decidable.recOn h h₂ h₁ : Sort u) :=
|
||||
Decidable.casesOn h (λ h, False.rec _ (h h₃)) (λ h, h₄)
|
||||
Decidable.casesOn h (fun h => False.rec _ (h h₃)) (fun h => h₄)
|
||||
|
||||
def recOnFalse [h : Decidable p] {h₁ : p → Sort u} {h₂ : ¬p → Sort u} (h₃ : ¬p) (h₄ : h₂ h₃)
|
||||
: (Decidable.recOn h h₂ h₁ : Sort u) :=
|
||||
Decidable.casesOn h (λ h, h₄) (λ h, False.rec _ (h₃ h))
|
||||
Decidable.casesOn h (fun h => h₄) (fun h => False.rec _ (h₃ h))
|
||||
|
||||
@[macroInline] def byCases {q : Sort u} [s : Decidable p] (h1 : p → q) (h2 : ¬p → q) : q :=
|
||||
match s with
|
||||
|
|
@ -923,21 +924,21 @@ theorem em (p : Prop) [Decidable p] : p ∨ ¬p :=
|
|||
byCases Or.inl Or.inr
|
||||
|
||||
theorem byContradiction [Decidable p] (h : ¬p → False) : p :=
|
||||
byCases id (λ np : ¬p, False.elim (h np))
|
||||
byCases id (fun np => False.elim (h np))
|
||||
|
||||
theorem ofNotNot [Decidable p] : ¬ ¬ p → p :=
|
||||
λ hnn, byContradiction (λ hn, absurd hn hnn)
|
||||
fun hnn => byContradiction (fun hn => absurd hn hnn)
|
||||
|
||||
theorem notNotIff (p) [Decidable p] : (¬ ¬ p) ↔ p :=
|
||||
Iff.intro ofNotNot notNotIntro
|
||||
|
||||
theorem notAndIffOrNot (p q : Prop) [d₁ : Decidable p] [d₂ : Decidable q] : ¬ (p ∧ q) ↔ ¬ p ∨ ¬ q :=
|
||||
Iff.intro
|
||||
(λ h, match d₁, d₂ with
|
||||
(fun h => match d₁, d₂ with
|
||||
| isTrue h₁, isTrue h₂ := absurd (And.intro h₁ h₂) h
|
||||
| _, isFalse h₂ := Or.inr h₂
|
||||
| isFalse h₁, _ := Or.inl h₁)
|
||||
(λ h ⟨hp, hq⟩, Or.elim h (λ h, h hp) (λ h, h hq))
|
||||
(fun (h) ⟨hp, hq⟩ => Or.elim h (fun h => h hp) (fun h => h hq))
|
||||
|
||||
end Decidable
|
||||
|
||||
|
|
@ -957,51 +958,51 @@ variables {p q : Prop}
|
|||
@[macroInline] instance [Decidable p] [Decidable q] : Decidable (p ∧ q) :=
|
||||
if hp : p then
|
||||
if hq : q then isTrue ⟨hp, hq⟩
|
||||
else isFalse (λ h : p ∧ q, hq (And.right h))
|
||||
else isFalse (λ h : p ∧ q, hp (And.left h))
|
||||
else isFalse (fun h => hq (And.right h))
|
||||
else isFalse (fun h => hp (And.left h))
|
||||
|
||||
@[macroInline] instance [Decidable p] [Decidable q] : Decidable (p ∨ q) :=
|
||||
if hp : p then isTrue (Or.inl hp) else
|
||||
if hq : q then isTrue (Or.inr hq) else
|
||||
isFalse (λ h, Or.elim h hp hq)
|
||||
isFalse (fun h => Or.elim h hp hq)
|
||||
|
||||
instance [Decidable p] : Decidable (¬p) :=
|
||||
if hp : p then isFalse (absurd hp) else isTrue hp
|
||||
|
||||
@[macroInline] instance implies.Decidable [Decidable p] [Decidable q] : Decidable (p → q) :=
|
||||
if hp : p then
|
||||
if hq : q then isTrue (λ h, hq)
|
||||
else isFalse (λ h : p → q, absurd (h hp) hq)
|
||||
else isTrue (λ h, absurd h hp)
|
||||
if hq : q then isTrue (fun h => hq)
|
||||
else isFalse (fun h => absurd (h hp) hq)
|
||||
else isTrue (fun h => absurd h hp)
|
||||
|
||||
instance [Decidable p] [Decidable q] : Decidable (p ↔ q) :=
|
||||
if hp : p then
|
||||
if hq : q then isTrue ⟨λ_, hq, λ_, hp⟩
|
||||
else isFalse $ λh, hq (h.1 hp)
|
||||
if hq : q then isTrue ⟨fun _ => hq, fun _ => hp⟩
|
||||
else isFalse $ fun h => hq (h.1 hp)
|
||||
else
|
||||
if hq : q then isFalse $ λh, hp (h.2 hq)
|
||||
else isTrue $ ⟨λh, absurd h hp, λh, absurd h hq⟩
|
||||
if hq : q then isFalse $ fun h => hp (h.2 hq)
|
||||
else isTrue $ ⟨fun h => absurd h hp, fun h => absurd h hq⟩
|
||||
|
||||
instance [Decidable p] [Decidable q] : Decidable (Xor p q) :=
|
||||
if hp : p then
|
||||
if hq : q then isFalse (λ h, Or.elim h (λ ⟨_, h⟩, h hq : ¬(p ∧ ¬ q)) (λ ⟨_, h⟩, h hp : ¬(q ∧ ¬ p)))
|
||||
if hq : q then isFalse (fun h => Or.elim h (fun ⟨_, h⟩ => h hq : ¬(p ∧ ¬ q)) (fun ⟨_, h⟩ => h hp : ¬(q ∧ ¬ p)))
|
||||
else isTrue $ Or.inl ⟨hp, hq⟩
|
||||
else
|
||||
if hq : q then isTrue $ Or.inr ⟨hq, hp⟩
|
||||
else isFalse (λ h, Or.elim h (λ ⟨h, _⟩, hp h : ¬(p ∧ ¬ q)) (λ ⟨h, _⟩, hq h : ¬(q ∧ ¬ p)))
|
||||
else isFalse (fun h => Or.elim h (fun ⟨h, _⟩ => hp h : ¬(p ∧ ¬ q)) (fun ⟨h, _⟩ => hq h : ¬(q ∧ ¬ p)))
|
||||
|
||||
end
|
||||
|
||||
@[inline] instance {α : Sort u} [DecidableEq α] (a b : α) : Decidable (a ≠ b) :=
|
||||
match decEq a b with
|
||||
| isTrue h := isFalse $ λ h', absurd h h'
|
||||
| isTrue h := isFalse $ fun h' => absurd h h'
|
||||
| isFalse h := isTrue h
|
||||
|
||||
theorem Bool.falseNeTrue (h : false = true) : False :=
|
||||
Bool.noConfusion h
|
||||
|
||||
instance : DecidableEq Bool :=
|
||||
{decEq := λ a b, match a, b with
|
||||
{decEq := fun a b => match a, b with
|
||||
| false, false := isTrue rfl
|
||||
| false, true := isFalse Bool.falseNeTrue
|
||||
| true, false := isFalse (Ne.symm Bool.falseNeTrue)
|
||||
|
|
@ -1020,7 +1021,7 @@ match h with
|
|||
| (isFalse hnc) := rfl
|
||||
|
||||
-- Remark: dite and ite are "defally equal" when we ignore the proofs.
|
||||
theorem difEqIf (c : Prop) [h : Decidable c] {α : Sort u} (t : α) (e : α) : dite c (λ h, t) (λ h, e) = ite c t e :=
|
||||
theorem difEqIf (c : Prop) [h : Decidable c] {α : Sort u} (t : α) (e : α) : dite c (fun h => t) (fun h => e) = ite c t e :=
|
||||
match h with
|
||||
| (isTrue hc) := rfl
|
||||
| (isFalse hnc) := rfl
|
||||
|
|
@ -1078,10 +1079,10 @@ instance Prop.Inhabited : Inhabited Prop :=
|
|||
⟨True⟩
|
||||
|
||||
instance Fun.Inhabited (α : Sort u) {β : Sort v} [h : Inhabited β] : Inhabited (α → β) :=
|
||||
Inhabited.casesOn h (λ b, ⟨λ a, b⟩)
|
||||
Inhabited.casesOn h (fun b => ⟨fun a => b⟩)
|
||||
|
||||
instance Pi.Inhabited (α : Sort u) {β : α → Sort v} [Π x, Inhabited (β x)] : Inhabited (Π x, β x) :=
|
||||
⟨λ a, default (β a)⟩
|
||||
⟨fun a => default (β a)⟩
|
||||
|
||||
instance : Inhabited Bool := ⟨false⟩
|
||||
|
||||
|
|
@ -1102,7 +1103,7 @@ Nonempty.rec h₂ h₁
|
|||
instance nonemptyOfInhabited {α : Sort u} [Inhabited α] : Nonempty α :=
|
||||
⟨default α⟩
|
||||
|
||||
theorem nonemptyOfExists {α : Sort u} {p : α → Prop} : Exists (λ x, p x) → Nonempty α
|
||||
theorem nonemptyOfExists {α : Sort u} {p : α → Prop} : Exists (fun x => p x) → Nonempty α
|
||||
| ⟨w, h⟩ := ⟨w⟩
|
||||
|
||||
/- Subsingleton -/
|
||||
|
|
@ -1111,22 +1112,22 @@ class inductive Subsingleton (α : Sort u) : Prop
|
|||
| intro (h : ∀ a b : α, a = b) : Subsingleton
|
||||
|
||||
protected def Subsingleton.elim {α : Sort u} [h : Subsingleton α] : ∀ (a b : α), a = b :=
|
||||
Subsingleton.casesOn h (λ p, p)
|
||||
Subsingleton.casesOn h (fun p => p)
|
||||
|
||||
protected def Subsingleton.helim {α β : Sort u} [h : Subsingleton α] (h : α = β) : ∀ (a : α) (b : β), a ≅ b :=
|
||||
Eq.recOn h (λ a b : α, heqOfEq (Subsingleton.elim a b))
|
||||
Eq.recOn h (fun a b => heqOfEq (Subsingleton.elim a b))
|
||||
|
||||
instance subsingletonProp (p : Prop) : Subsingleton p :=
|
||||
⟨λ a b, proofIrrel a b⟩
|
||||
⟨fun a b => proofIrrel a b⟩
|
||||
|
||||
instance (p : Prop) : Subsingleton (Decidable p) :=
|
||||
Subsingleton.intro (λ d₁,
|
||||
Subsingleton.intro (fun d₁ =>
|
||||
match d₁ with
|
||||
| (isTrue t₁) := (λ d₂,
|
||||
| (isTrue t₁) := (fun d₂ =>
|
||||
match d₂ with
|
||||
| (isTrue t₂) := Eq.recOn (proofIrrel t₁ t₂) rfl
|
||||
| (isFalse f₂) := absurd t₁ f₂)
|
||||
| (isFalse f₁) := (λ d₂,
|
||||
| (isFalse f₁) := (fun d₂ =>
|
||||
match d₂ with
|
||||
| (isTrue t₂) := absurd t₂ f₁
|
||||
| (isFalse f₂) := Eq.recOn (proofIrrel f₁ f₂) rfl))
|
||||
|
|
@ -1158,18 +1159,18 @@ def Irreflexive := ∀ x, ¬ r x x
|
|||
|
||||
def AntiSymmetric := ∀ {x y}, r x y → r y x → x = y
|
||||
|
||||
def emptyRelation := λ a₁ a₂ : α, False
|
||||
def emptyRelation := fun a₁ a₂ : α => False
|
||||
|
||||
def Subrelation (q r : β → β → Prop) := ∀ {x y}, q x y → r x y
|
||||
|
||||
def InvImage (f : α → β) : α → α → Prop :=
|
||||
λ a₁ a₂, r (f a₁) (f a₂)
|
||||
fun a₁ a₂ => r (f a₁) (f a₂)
|
||||
|
||||
theorem InvImage.Transitive (f : α → β) (h : Transitive r) : Transitive (InvImage r f) :=
|
||||
λ (a₁ a₂ a₃ : α) (h₁ : InvImage r f a₁ a₂) (h₂ : InvImage r f a₂ a₃), h h₁ h₂
|
||||
fun (a₁ a₂ a₃ : α) (h₁ : InvImage r f a₁ a₂) (h₂ : InvImage r f a₂ a₃) => h h₁ h₂
|
||||
|
||||
theorem InvImage.Irreflexive (f : α → β) (h : Irreflexive r) : Irreflexive (InvImage r f) :=
|
||||
λ (a : α) (h₁ : InvImage r f a a), h (f a) h₁
|
||||
fun (a : α) (h₁ : InvImage r f a a) => h (f a) h₁
|
||||
|
||||
inductive TC {α : Sort u} (r : α → α → Prop) : α → α → Prop
|
||||
| base : ∀ a b, r a b → TC a b
|
||||
|
|
@ -1180,7 +1181,7 @@ theorem TC.ndrec.{u1, u2} {α : Sort u} {r : α → α → Prop} {C : α → α
|
|||
(m₁ : ∀ (a b : α), r a b → C a b)
|
||||
(m₂ : ∀ (a b c : α), TC r a b → TC r b c → C a b → C b c → C a c)
|
||||
{a b : α} (h : TC r a b) : C a b :=
|
||||
@TC.rec α r (λ a b _, C a b) m₁ m₂ a b h
|
||||
@TC.rec α r (fun a b _ => C a b) m₁ m₂ a b h
|
||||
|
||||
@[elabAsEliminator]
|
||||
theorem TC.ndrecOn.{u1, u2} {α : Sort u} {r : α → α → Prop} {C : α → α → Prop}
|
||||
|
|
@ -1188,7 +1189,7 @@ theorem TC.ndrecOn.{u1, u2} {α : Sort u} {r : α → α → Prop} {C : α →
|
|||
(m₁ : ∀ (a b : α), r a b → C a b)
|
||||
(m₂ : ∀ (a b c : α), TC r a b → TC r b c → C a b → C b c → C a c)
|
||||
: C a b :=
|
||||
@TC.rec α r (λ a b _, C a b) m₁ m₂ a b h
|
||||
@TC.rec α r (fun a b _ => C a b) m₁ m₂ a b h
|
||||
|
||||
end relation
|
||||
|
||||
|
|
@ -1202,11 +1203,11 @@ def RightCommutative (h : β → α → β) := ∀ b a₁ a₂, h (h b a₁) a
|
|||
def LeftCommutative (h : α → β → β) := ∀ a₁ a₂ b, h a₁ (h a₂ b) = h a₂ (h a₁ b)
|
||||
|
||||
theorem leftComm : Commutative f → Associative f → LeftCommutative f :=
|
||||
λ hcomm hassoc, λ a b c,
|
||||
fun hcomm hassoc a b c =>
|
||||
((Eq.symm (hassoc a b c)).trans (hcomm a b ▸ rfl : f (f a b) c = f (f b a) c)).trans (hassoc b a c)
|
||||
|
||||
theorem rightComm : Commutative f → Associative f → RightCommutative f :=
|
||||
λ hcomm hassoc, λ a b c,
|
||||
fun hcomm hassoc a b c =>
|
||||
((hassoc a b c).trans (hcomm b c ▸ rfl : f a (f b c) = f a (f c b))).trans (Eq.symm (hassoc a c b))
|
||||
|
||||
end Binary
|
||||
|
|
@ -1214,7 +1215,7 @@ end Binary
|
|||
/- Subtype -/
|
||||
|
||||
namespace Subtype
|
||||
def existsOfSubtype {α : Type u} {p : α → Prop} : { x // p x } → Exists (λ x, p x)
|
||||
def existsOfSubtype {α : Type u} {p : α → Prop} : { x // p x } → Exists (fun x => p x)
|
||||
| ⟨a, h⟩ := ⟨a, h⟩
|
||||
|
||||
variables {α : Type u} {p : α → Prop}
|
||||
|
|
@ -1232,9 +1233,9 @@ instance {α : Type u} {p : α → Prop} {a : α} (h : p a) : Inhabited {x // p
|
|||
⟨⟨a, h⟩⟩
|
||||
|
||||
instance {α : Type u} {p : α → Prop} [DecidableEq α] : DecidableEq {x : α // p x} :=
|
||||
{decEq := λ ⟨a, h₁⟩ ⟨b, h₂⟩,
|
||||
{decEq := fun ⟨a, h₁⟩ ⟨b, h₂⟩ =>
|
||||
if h : a = b then isTrue (Subtype.eq h)
|
||||
else isFalse (λ h', Subtype.noConfusion h' (λ h', absurd h' h))}
|
||||
else isFalse (fun h' => Subtype.noConfusion h' (fun h' => absurd h' h))}
|
||||
end Subtype
|
||||
|
||||
/- Sum -/
|
||||
|
|
@ -1251,14 +1252,14 @@ instance Sum.inhabitedRight [h : Inhabited β] : Inhabited (α ⊕ β) :=
|
|||
⟨Sum.inr (default β)⟩
|
||||
|
||||
instance {α : Type u} {β : Type v} [DecidableEq α] [DecidableEq β] : DecidableEq (α ⊕ β) :=
|
||||
{decEq := λ a b,
|
||||
{decEq := fun a b =>
|
||||
match a, b with
|
||||
| (Sum.inl a), (Sum.inl b) := if h : a = b then isTrue (h ▸ rfl)
|
||||
else isFalse (λ h', Sum.noConfusion h' (λ h', absurd h' h))
|
||||
else isFalse (fun h' => Sum.noConfusion h' (fun h' => absurd h' h))
|
||||
| (Sum.inr a), (Sum.inr b) := if h : a = b then isTrue (h ▸ rfl)
|
||||
else isFalse (λ h', Sum.noConfusion h' (λ h', absurd h' h))
|
||||
| (Sum.inr a), (Sum.inl b) := isFalse (λ h, Sum.noConfusion h)
|
||||
| (Sum.inl a), (Sum.inr b) := isFalse (λ h, Sum.noConfusion h)}
|
||||
else isFalse (fun h' => Sum.noConfusion h' (fun h' => absurd h' h))
|
||||
| (Sum.inr a), (Sum.inl b) := isFalse (fun h => Sum.noConfusion h)
|
||||
| (Sum.inl a), (Sum.inr b) := isFalse (fun h => Sum.noConfusion h)}
|
||||
end
|
||||
|
||||
/- Product -/
|
||||
|
|
@ -1270,22 +1271,22 @@ instance [Inhabited α] [Inhabited β] : Inhabited (Prod α β) :=
|
|||
⟨(default α, default β)⟩
|
||||
|
||||
instance [DecidableEq α] [DecidableEq β] : DecidableEq (α × β) :=
|
||||
{decEq := λ ⟨a, b⟩ ⟨a', b'⟩,
|
||||
{decEq := fun ⟨a, b⟩ ⟨a', b'⟩ =>
|
||||
match (decEq a a') with
|
||||
| (isTrue e₁) :=
|
||||
(match (decEq b b') with
|
||||
| (isTrue e₂) := isTrue (Eq.recOn e₁ (Eq.recOn e₂ rfl))
|
||||
| (isFalse n₂) := isFalse (λ h, Prod.noConfusion h (λ e₁' e₂', absurd e₂' n₂)))
|
||||
| (isFalse n₁) := isFalse (λ h, Prod.noConfusion h (λ e₁' e₂', absurd e₁' n₁))}
|
||||
| (isFalse n₂) := isFalse (fun h => Prod.noConfusion h (fun e₁' e₂' => absurd e₂' n₂)))
|
||||
| (isFalse n₁) := isFalse (fun h => Prod.noConfusion h (fun e₁' e₂' => absurd e₁' n₁))}
|
||||
|
||||
instance [HasLess α] [HasLess β] : HasLess (α × β) :=
|
||||
⟨λ s t, s.1 < t.1 ∨ (s.1 = t.1 ∧ s.2 < t.2)⟩
|
||||
⟨fun s t => s.1 < t.1 ∨ (s.1 = t.1 ∧ s.2 < t.2)⟩
|
||||
|
||||
instance prodHasDecidableLt
|
||||
[HasLess α] [HasLess β] [DecidableEq α] [DecidableEq β]
|
||||
[Π a b : α, Decidable (a < b)] [Π a b : β, Decidable (a < b)]
|
||||
: Π s t : α × β, Decidable (s < t) :=
|
||||
λ t s, Or.Decidable
|
||||
fun t s => Or.Decidable
|
||||
|
||||
theorem Prod.ltDef [HasLess α] [HasLess β] (s t : α × β) : (s < t) = (s.1 < t.1 ∨ (s.1 = t.1 ∧ s.2 < t.2)) :=
|
||||
rfl
|
||||
|
|
@ -1300,13 +1301,13 @@ def Prod.map.{u₁, u₂, v₁, v₂} {α₁ : Type u₁} {α₂ : Type u₂} {
|
|||
-- notation `Σ` binders `, ` r:(scoped p, Sigma p) := r
|
||||
-- notation `Σ'` binders `, ` r:(scoped p, PSigma p) := r
|
||||
|
||||
theorem exOfPsig {α : Type u} {p : α → Prop} : (PSigma (λ x, p x)) → Exists (λ x, p x)
|
||||
theorem exOfPsig {α : Type u} {p : α → Prop} : (PSigma (fun x => p x)) → Exists (fun x => p x)
|
||||
| ⟨x, hx⟩ := ⟨x, hx⟩
|
||||
|
||||
section
|
||||
variables {α : Type u} {β : α → Type v}
|
||||
|
||||
protected theorem Sigma.eq : ∀ {p₁ p₂ : Sigma (λ a : α, β a)} (h₁ : p₁.1 = p₂.1), (Eq.recOn h₁ p₁.2 : β p₂.1) = p₂.2 → p₁ = p₂
|
||||
protected theorem Sigma.eq : ∀ {p₁ p₂ : Sigma (fun a => β a)} (h₁ : p₁.1 = p₂.1), (Eq.recOn h₁ p₁.2 : β p₂.1) = p₂.2 → p₁ = p₂
|
||||
| ⟨a, b⟩ ⟨.(a), .(b)⟩ rfl rfl := rfl
|
||||
end
|
||||
|
||||
|
|
@ -1332,7 +1333,7 @@ instance : Inhabited PUnit :=
|
|||
⟨⟨⟩⟩
|
||||
|
||||
instance : DecidableEq PUnit :=
|
||||
{decEq := λ a b, isTrue (punitEq a b)}
|
||||
{decEq := fun a b => isTrue (punitEq a b)}
|
||||
|
||||
/- Setoid -/
|
||||
|
||||
|
|
@ -1393,8 +1394,8 @@ lift f c q
|
|||
protected theorem inductionOn {α : Sort u} {r : α → α → Prop} {β : Quot r → Prop} (q : Quot r) (h : ∀ a, β (Quot.mk r a)) : β q :=
|
||||
ind h q
|
||||
|
||||
theorem existsRep {α : Sort u} {r : α → α → Prop} (q : Quot r) : Exists (λ a : α, (Quot.mk r a) = q) :=
|
||||
Quot.inductionOn q (λ a, ⟨a, rfl⟩)
|
||||
theorem existsRep {α : Sort u} {r : α → α → Prop} (q : Quot r) : Exists (fun a => (Quot.mk r a) = q) :=
|
||||
Quot.inductionOn q (fun a => ⟨a, rfl⟩)
|
||||
|
||||
section
|
||||
variable {α : Sort u}
|
||||
|
|
@ -1408,12 +1409,12 @@ protected def indep (f : Π a, β (Quot.mk r a)) (a : α) : PSigma β :=
|
|||
protected theorem indepCoherent (f : Π a, β (Quot.mk r a))
|
||||
(h : ∀ (a b : α) (p : r a b), (Eq.rec (f a) (sound p) : β (Quot.mk r b)) = f b)
|
||||
: ∀ a b, r a b → Quot.indep f a = Quot.indep f b :=
|
||||
λ a b e, PSigma.eq (sound e) (h a b e)
|
||||
fun a b e => PSigma.eq (sound e) (h a b e)
|
||||
|
||||
protected theorem liftIndepPr1
|
||||
(f : Π a, β (Quot.mk r a)) (h : ∀ (a b : α) (p : r a b), (Eq.rec (f a) (sound p) : β (Quot.mk r b)) = f b)
|
||||
(q : Quot r) : (lift (Quot.indep f) (Quot.indepCoherent f h) q).1 = q :=
|
||||
Quot.ind (λ (a : α), Eq.refl (Quot.indep f a).1) q
|
||||
Quot.ind (fun (a : α) => Eq.refl (Quot.indep f a).1) q
|
||||
|
||||
@[reducible, elabAsEliminator, inline]
|
||||
protected def rec
|
||||
|
|
@ -1429,13 +1430,13 @@ Quot.rec f h q
|
|||
@[reducible, elabAsEliminator, inline]
|
||||
protected def recOnSubsingleton
|
||||
[h : ∀ a, Subsingleton (β (Quot.mk r a))] (q : Quot r) (f : Π a, β (Quot.mk r a)) : β q :=
|
||||
Quot.rec f (λ a b h, Subsingleton.elim _ (f b)) q
|
||||
Quot.rec f (fun a b h => Subsingleton.elim _ (f b)) q
|
||||
|
||||
@[reducible, elabAsEliminator, inline]
|
||||
protected def hrecOn
|
||||
(q : Quot r) (f : Π a, β (Quot.mk r a)) (c : ∀ (a b : α) (p : r a b), f a ≅ f b) : β q :=
|
||||
Quot.recOn q f $
|
||||
λ a b p, eqOfHeq $
|
||||
fun a b p => eqOfHeq $
|
||||
have p₁ : (Eq.rec (f a) (sound p) : β (Quot.mk r b)) ≅ f a, from eqRecHeq (sound p) (f a),
|
||||
Heq.trans p₁ (c a b p)
|
||||
|
||||
|
|
@ -1472,7 +1473,7 @@ Quot.liftOn q f c
|
|||
protected theorem inductionOn {α : Sort u} [s : Setoid α] {β : Quotient s → Prop} (q : Quotient s) (h : ∀ a, β ⟦a⟧) : β q :=
|
||||
Quot.inductionOn q h
|
||||
|
||||
theorem existsRep {α : Sort u} [s : Setoid α] (q : Quotient s) : Exists (λ a : α, ⟦a⟧ = q) :=
|
||||
theorem existsRep {α : Sort u} [s : Setoid α] (q : Quotient s) : Exists (fun a : α => ⟦a⟧ = q) :=
|
||||
Quot.existsRep q
|
||||
|
||||
section
|
||||
|
|
@ -1512,14 +1513,14 @@ protected def lift₂
|
|||
(f : α → β → φ)(c : ∀ a₁ a₂ b₁ b₂, a₁ ≈ b₁ → a₂ ≈ b₂ → f a₁ a₂ = f b₁ b₂)
|
||||
(q₁ : Quotient s₁) (q₂ : Quotient s₂) : φ :=
|
||||
Quotient.lift
|
||||
(λ (a₁ : α), Quotient.lift (f a₁) (λ (a b : β), c a₁ a a₁ b (Setoid.refl a₁)) q₂)
|
||||
(λ (a b : α) (h : a ≈ b),
|
||||
(fun (a₁ : α) => Quotient.lift (f a₁) (fun (a b : β) => c a₁ a a₁ b (Setoid.refl a₁)) q₂)
|
||||
(fun (a b : α) (h : a ≈ b) =>
|
||||
@Quotient.ind β s₂
|
||||
(λ (a1 : Quotient s₂),
|
||||
(Quotient.lift (f a) (λ (a1 b : β), c a a1 a b (Setoid.refl a)) a1)
|
||||
(fun (a1 : Quotient s₂) =>
|
||||
(Quotient.lift (f a) (fun (a1 b : β) => c a a1 a b (Setoid.refl a)) a1)
|
||||
=
|
||||
(Quotient.lift (f b) (λ (a b1 : β), c b a b b1 (Setoid.refl b)) a1))
|
||||
(λ (a' : β), c a a' b a' h (Setoid.refl a'))
|
||||
(Quotient.lift (f b) (fun (a b1 : β) => c b a b b1 (Setoid.refl b)) a1))
|
||||
(fun (a' : β) => c a a' b a' h (Setoid.refl a'))
|
||||
q₂)
|
||||
q₁
|
||||
|
||||
|
|
@ -1530,19 +1531,19 @@ Quotient.lift₂ f c q₁ q₂
|
|||
|
||||
@[elabAsEliminator]
|
||||
protected theorem ind₂ {φ : Quotient s₁ → Quotient s₂ → Prop} (h : ∀ a b, φ ⟦a⟧ ⟦b⟧) (q₁ : Quotient s₁) (q₂ : Quotient s₂) : φ q₁ q₂ :=
|
||||
Quotient.ind (λ a₁, Quotient.ind (λ a₂, h a₁ a₂) q₂) q₁
|
||||
Quotient.ind (fun a₁ => Quotient.ind (fun a₂ => h a₁ a₂) q₂) q₁
|
||||
|
||||
@[elabAsEliminator]
|
||||
protected theorem inductionOn₂
|
||||
{φ : Quotient s₁ → Quotient s₂ → Prop} (q₁ : Quotient s₁) (q₂ : Quotient s₂) (h : ∀ a b, φ ⟦a⟧ ⟦b⟧) : φ q₁ q₂ :=
|
||||
Quotient.ind (λ a₁, Quotient.ind (λ a₂, h a₁ a₂) q₂) q₁
|
||||
Quotient.ind (fun a₁ => Quotient.ind (fun a₂ => h a₁ a₂) q₂) q₁
|
||||
|
||||
@[elabAsEliminator]
|
||||
protected theorem inductionOn₃
|
||||
[s₃ : Setoid φ]
|
||||
{δ : Quotient s₁ → Quotient s₂ → Quotient s₃ → Prop} (q₁ : Quotient s₁) (q₂ : Quotient s₂) (q₃ : Quotient s₃) (h : ∀ a b c, δ ⟦a⟧ ⟦b⟧ ⟦c⟧)
|
||||
: δ q₁ q₂ q₃ :=
|
||||
Quotient.ind (λ a₁, Quotient.ind (λ a₂, Quotient.ind (λ a₃, h a₁ a₂ a₃) q₃) q₂) q₁
|
||||
Quotient.ind (fun a₁ => Quotient.ind (fun a₂ => Quotient.ind (fun a₃ => h a₁ a₂ a₃) q₃) q₂) q₁
|
||||
end
|
||||
|
||||
section Exact
|
||||
|
|
@ -1550,20 +1551,20 @@ variable {α : Sort u}
|
|||
|
||||
private def rel [s : Setoid α] (q₁ q₂ : Quotient s) : Prop :=
|
||||
Quotient.liftOn₂ q₁ q₂
|
||||
(λ a₁ a₂, a₁ ≈ a₂)
|
||||
(λ a₁ a₂ b₁ b₂ a₁b₁ a₂b₂,
|
||||
(fun a₁ a₂ => a₁ ≈ a₂)
|
||||
(fun a₁ a₂ b₁ b₂ a₁b₁ a₂b₂ =>
|
||||
propext (Iff.intro
|
||||
(λ a₁a₂, Setoid.trans (Setoid.symm a₁b₁) (Setoid.trans a₁a₂ a₂b₂))
|
||||
(λ b₁b₂, Setoid.trans a₁b₁ (Setoid.trans b₁b₂ (Setoid.symm a₂b₂)))))
|
||||
(fun a₁a₂ => Setoid.trans (Setoid.symm a₁b₁) (Setoid.trans a₁a₂ a₂b₂))
|
||||
(fun b₁b₂ => Setoid.trans a₁b₁ (Setoid.trans b₁b₂ (Setoid.symm a₂b₂)))))
|
||||
|
||||
private theorem rel.refl [s : Setoid α] : ∀ q : Quotient s, rel q q :=
|
||||
λ q, Quot.inductionOn q (λ a, Setoid.refl a)
|
||||
fun q => Quot.inductionOn q (fun a => Setoid.refl a)
|
||||
|
||||
private theorem eqImpRel [s : Setoid α] {q₁ q₂ : Quotient s} : q₁ = q₂ → rel q₁ q₂ :=
|
||||
λ h, Eq.ndrecOn h (rel.refl q₁)
|
||||
fun h => Eq.ndrecOn h (rel.refl q₁)
|
||||
|
||||
theorem exact [s : Setoid α] {a b : α} : ⟦a⟧ = ⟦b⟧ → a ≈ b :=
|
||||
λ h, eqImpRel h
|
||||
fun h => eqImpRel h
|
||||
end Exact
|
||||
|
||||
section
|
||||
|
|
@ -1575,8 +1576,8 @@ variables [s₁ : Setoid α] [s₂ : Setoid β]
|
|||
protected def recOnSubsingleton₂
|
||||
{φ : Quotient s₁ → Quotient s₂ → Sort uC} [h : ∀ a b, Subsingleton (φ ⟦a⟧ ⟦b⟧)]
|
||||
(q₁ : Quotient s₁) (q₂ : Quotient s₂) (f : Π a b, φ ⟦a⟧ ⟦b⟧) : φ q₁ q₂:=
|
||||
@Quotient.recOnSubsingleton _ s₁ (λ q, φ q q₂) (λ a, Quotient.ind (λ b, h a b) q₂) q₁
|
||||
(λ a, Quotient.recOnSubsingleton q₂ (λ b, f a b))
|
||||
@Quotient.recOnSubsingleton _ s₁ (fun q => φ q q₂) (fun a => Quotient.ind (fun b => h a b) q₂) q₁
|
||||
(fun a => Quotient.recOnSubsingleton q₂ (fun b => f a b))
|
||||
|
||||
end
|
||||
end Quotient
|
||||
|
|
@ -1599,23 +1600,23 @@ Setoid.mk _ (EqvGen.isEquivalence r)
|
|||
|
||||
theorem Quot.exact {a b : α} (H : Quot.mk r a = Quot.mk r b) : EqvGen r a b :=
|
||||
@Quotient.exact _ (EqvGen.Setoid r) a b (@congrArg _ _ _ _
|
||||
(Quot.lift (@Quotient.mk _ (EqvGen.Setoid r)) (λx y h, Quot.sound (EqvGen.rel x y h))) H)
|
||||
(Quot.lift (@Quotient.mk _ (EqvGen.Setoid r)) (fun x y h => Quot.sound (EqvGen.rel x y h))) H)
|
||||
|
||||
theorem Quot.eqvGenSound {r : α → α → Prop} {a b : α} (H : EqvGen r a b) : Quot.mk r a = Quot.mk r b :=
|
||||
EqvGen.recOn H
|
||||
(λ x y h, Quot.sound h)
|
||||
(λ x, rfl)
|
||||
(λ x y _ IH, Eq.symm IH)
|
||||
(λ x y z _ _ IH₁ IH₂, Eq.trans IH₁ IH₂)
|
||||
(fun x y h => Quot.sound h)
|
||||
(fun x => rfl)
|
||||
(fun x y _ IH => Eq.symm IH)
|
||||
(fun x y z _ _ IH₁ IH₂ => Eq.trans IH₁ IH₂)
|
||||
end
|
||||
|
||||
instance {α : Sort u} {s : Setoid α} [d : ∀ a b : α, Decidable (a ≈ b)] : DecidableEq (Quotient s) :=
|
||||
{decEq := λ q₁ q₂ : Quotient s,
|
||||
{decEq := fun (q₁ q₂ : Quotient s) =>
|
||||
Quotient.recOnSubsingleton₂ q₁ q₂
|
||||
(λ a₁ a₂,
|
||||
(fun a₁ a₂ =>
|
||||
match (d a₁ a₂) with
|
||||
| (isTrue h₁) := isTrue (Quotient.sound h₁)
|
||||
| (isFalse h₂) := isFalse (λ h, absurd (Quotient.exact h) h₂))}
|
||||
| (isFalse h₂) := isFalse (fun h => absurd (Quotient.exact h) h₂))}
|
||||
|
||||
/- Function extensionality -/
|
||||
|
||||
|
|
@ -1624,13 +1625,14 @@ variables {α : Sort u} {β : α → Sort v}
|
|||
|
||||
def Equiv (f₁ f₂ : Π x : α, β x) : Prop := ∀ x, f₁ x = f₂ x
|
||||
|
||||
protected theorem Equiv.refl (f : Π x : α, β x) : Equiv f f := λ x, rfl
|
||||
protected theorem Equiv.refl (f : Π x : α, β x) : Equiv f f :=
|
||||
fun x => rfl
|
||||
|
||||
protected theorem Equiv.symm {f₁ f₂ : Π x: α, β x} : Equiv f₁ f₂ → Equiv f₂ f₁ :=
|
||||
λ h x, Eq.symm (h x)
|
||||
fun h x => Eq.symm (h x)
|
||||
|
||||
protected theorem Equiv.trans {f₁ f₂ f₃ : Π x: α, β x} : Equiv f₁ f₂ → Equiv f₂ f₃ → Equiv f₁ f₃ :=
|
||||
λ h₁ h₂ x, Eq.trans (h₁ x) (h₂ x)
|
||||
fun h₁ h₂ x => Eq.trans (h₁ x) (h₂ x)
|
||||
|
||||
protected theorem Equiv.isEquivalence (α : Sort u) (β : α → Sort v) : Equivalence (@Function.Equiv α β) :=
|
||||
mkEquivalence (@Function.Equiv α β) (@Equiv.refl α β) (@Equiv.symm α β) (@Equiv.trans α β)
|
||||
|
|
@ -1645,10 +1647,10 @@ private def funSetoid (α : Sort u) (β : α → Sort v) : Setoid (Π x : α, β
|
|||
Setoid.mk (@Function.Equiv α β) (Function.Equiv.isEquivalence α β)
|
||||
|
||||
private def extfunApp (f : Quotient $ funSetoid α β) : Π x : α, β x :=
|
||||
λ x,
|
||||
fun x =>
|
||||
Quot.liftOn f
|
||||
(λ f : Π x : α, β x, f x)
|
||||
(λ f₁ f₂ h, h x)
|
||||
(fun (f : Π x : α, β x) => f x)
|
||||
(fun f₁ f₂ h => h x)
|
||||
|
||||
theorem funext {f₁ f₂ : Π x : α, β x} (h : ∀ x, f₁ x = f₂ x) : f₁ = f₂ :=
|
||||
show extfunApp ⟦f₁⟧ = extfunApp ⟦f₂⟧, from
|
||||
|
|
@ -1656,7 +1658,7 @@ congrArg extfunApp (sound h)
|
|||
end
|
||||
|
||||
instance Pi.Subsingleton {α : Sort u} {β : α → Sort v} [∀ a, Subsingleton (β a)] : Subsingleton (Π a, β a) :=
|
||||
⟨λ f₁ f₂, funext (λ a, Subsingleton.elim (f₁ a) (f₂ a))⟩
|
||||
⟨fun f₁ f₂ => funext (fun a => Subsingleton.elim (f₁ a) (f₂ a))⟩
|
||||
|
||||
/- General operations on functions -/
|
||||
namespace Function
|
||||
|
|
@ -1664,22 +1666,22 @@ universes u₁ u₂ u₃ u₄
|
|||
variables {α : Sort u₁} {β : Sort u₂} {φ : Sort u₃} {δ : Sort u₄} {ζ : Sort u₁}
|
||||
|
||||
@[inline, reducible] def comp (f : β → φ) (g : α → β) : α → φ :=
|
||||
λ x, f (g x)
|
||||
fun x => f (g x)
|
||||
|
||||
infixr ` ∘ ` := Function.comp
|
||||
|
||||
@[inline, reducible] def onFun (f : β → β → φ) (g : α → β) : α → α → φ :=
|
||||
λ x y, f (g x) (g y)
|
||||
fun x y => f (g x) (g y)
|
||||
|
||||
@[inline, reducible] def combine (f : α → β → φ) (op : φ → δ → ζ) (g : α → β → δ)
|
||||
: α → β → ζ :=
|
||||
λ x y, op (f x y) (g x y)
|
||||
fun x y => op (f x y) (g x y)
|
||||
|
||||
@[inline, reducible] def const (β : Sort u₂) (a : α) : β → α :=
|
||||
λ x, a
|
||||
fun x => a
|
||||
|
||||
@[inline, reducible] def swap {φ : α → β → Sort u₃} (f : Π x y, φ x y) : Π y x, φ x y :=
|
||||
λ y x, f x y
|
||||
fun y x => f x y
|
||||
|
||||
end Function
|
||||
|
||||
|
|
@ -1690,86 +1692,86 @@ namespace Classical
|
|||
axiom choice {α : Sort u} : Nonempty α → α
|
||||
|
||||
noncomputable def indefiniteDescription {α : Sort u} (p : α → Prop)
|
||||
(h : Exists (λ x, p x)) : {x // p x} :=
|
||||
(h : Exists (fun x => p x)) : {x // p x} :=
|
||||
choice $ let ⟨x, px⟩ := h; ⟨⟨x, px⟩⟩
|
||||
|
||||
noncomputable def choose {α : Sort u} {p : α → Prop} (h : Exists (λ x, p x)) : α :=
|
||||
noncomputable def choose {α : Sort u} {p : α → Prop} (h : Exists (fun x => p x)) : α :=
|
||||
(indefiniteDescription p h).val
|
||||
|
||||
theorem chooseSpec {α : Sort u} {p : α → Prop} (h : Exists (λ x, p x)) : p (choose h) :=
|
||||
theorem chooseSpec {α : Sort u} {p : α → Prop} (h : Exists (fun x => p x)) : p (choose h) :=
|
||||
(indefiniteDescription p h).property
|
||||
|
||||
/- Diaconescu's theorem: excluded middle from choice, Function extensionality and propositional extensionality. -/
|
||||
theorem em (p : Prop) : p ∨ ¬p :=
|
||||
let U (x : Prop) : Prop := x = True ∨ p;
|
||||
let V (x : Prop) : Prop := x = False ∨ p;
|
||||
have exU : Exists (λ x, U x), from ⟨True, Or.inl rfl⟩,
|
||||
have exV : Exists (λ x, V x), from ⟨False, Or.inl rfl⟩,
|
||||
have exU : Exists (fun x => U x), from ⟨True, Or.inl rfl⟩,
|
||||
have exV : Exists (fun x => V x), from ⟨False, Or.inl rfl⟩,
|
||||
let u : Prop := choose exU;
|
||||
let v : Prop := choose exV;
|
||||
have uDef : U u, from chooseSpec exU,
|
||||
have vDef : V v, from chooseSpec exV,
|
||||
have notUvOrP : u ≠ v ∨ p, from
|
||||
Or.elim uDef
|
||||
(λ hut : u = True,
|
||||
(fun hut : u = True =>
|
||||
Or.elim vDef
|
||||
(λ hvf : v = False,
|
||||
(fun hvf : v = False =>
|
||||
have hne : u ≠ v, from hvf.symm ▸ hut.symm ▸ trueNeFalse,
|
||||
Or.inl hne)
|
||||
Or.inr)
|
||||
Or.inr,
|
||||
have pImpliesUv : p → u = v, from
|
||||
λ hp : p,
|
||||
fun hp : p =>
|
||||
have hpred : U = V, from
|
||||
funext $ λ x : Prop,
|
||||
funext $ fun x : Prop =>
|
||||
have hl : (x = True ∨ p) → (x = False ∨ p), from
|
||||
λ a, Or.inr hp,
|
||||
fun a => Or.inr hp,
|
||||
have hr : (x = False ∨ p) → (x = True ∨ p), from
|
||||
λ a, Or.inr hp,
|
||||
fun a => Or.inr hp,
|
||||
show (x = True ∨ p) = (x = False ∨ p), from
|
||||
propext (Iff.intro hl hr),
|
||||
have h₀ : ∀ exU exV, @choose _ U exU = @choose _ V exV, from
|
||||
hpred ▸ λ exU exV, rfl,
|
||||
hpred ▸ fun exU exV => rfl,
|
||||
show u = v, from h₀ _ _,
|
||||
Or.elim notUvOrP
|
||||
(λ hne : u ≠ v, Or.inr (mt pImpliesUv hne))
|
||||
(fun (hne : u ≠ v) => Or.inr (mt pImpliesUv hne))
|
||||
Or.inl
|
||||
|
||||
theorem existsTrueOfNonempty {α : Sort u} : Nonempty α → Exists (λ x : α, True)
|
||||
theorem existsTrueOfNonempty {α : Sort u} : Nonempty α → Exists (fun x : α => True)
|
||||
| ⟨x⟩ := ⟨x, trivial⟩
|
||||
|
||||
noncomputable def inhabitedOfNonempty {α : Sort u} (h : Nonempty α) : Inhabited α :=
|
||||
⟨choice h⟩
|
||||
|
||||
noncomputable def inhabitedOfExists {α : Sort u} {p : α → Prop} (h : Exists (λ x, p x)) :
|
||||
noncomputable def inhabitedOfExists {α : Sort u} {p : α → Prop} (h : Exists (fun x => p x)) :
|
||||
Inhabited α :=
|
||||
inhabitedOfNonempty (Exists.elim h (λ w hw, ⟨w⟩))
|
||||
inhabitedOfNonempty (Exists.elim h (fun w hw => ⟨w⟩))
|
||||
|
||||
/- all propositions are Decidable -/
|
||||
noncomputable def propDecidable (a : Prop) : Decidable a :=
|
||||
choice $ Or.elim (em a)
|
||||
(λ ha, ⟨isTrue ha⟩)
|
||||
(λ hna, ⟨isFalse hna⟩)
|
||||
(fun ha => ⟨isTrue ha⟩)
|
||||
(fun hna => ⟨isFalse hna⟩)
|
||||
|
||||
noncomputable def decidableInhabited (a : Prop) : Inhabited (Decidable a) :=
|
||||
⟨propDecidable a⟩
|
||||
|
||||
noncomputable def typeDecidableEq (α : Sort u) : DecidableEq α :=
|
||||
{decEq := λ x y, propDecidable (x = y)}
|
||||
{decEq := fun x y => propDecidable (x = y)}
|
||||
|
||||
noncomputable def typeDecidable (α : Sort u) : PSum α (α → False) :=
|
||||
match (propDecidable (Nonempty α)) with
|
||||
| (isTrue hp) := PSum.inl (@Inhabited.default _ (inhabitedOfNonempty hp))
|
||||
| (isFalse hn) := PSum.inr (λ a, absurd (Nonempty.intro a) hn)
|
||||
| (isFalse hn) := PSum.inr (fun a => absurd (Nonempty.intro a) hn)
|
||||
|
||||
noncomputable def strongIndefiniteDescription {α : Sort u} (p : α → Prop)
|
||||
(h : Nonempty α) : {x : α // Exists (λ y : α, p y) → p x} :=
|
||||
@dite (Exists (λ x : α, p x)) (propDecidable _) _
|
||||
(λ hp : Exists (λ x : α, p x),
|
||||
show {x : α // Exists (λ y : α, p y) → p x}, from
|
||||
(h : Nonempty α) : {x : α // Exists (fun y : α => p y) → p x} :=
|
||||
@dite (Exists (fun x : α => p x)) (propDecidable _) _
|
||||
(fun hp : Exists (fun x : α => p x) =>
|
||||
show {x : α // Exists (fun y : α => p y) → p x}, from
|
||||
let xp := indefiniteDescription _ hp;
|
||||
⟨xp.val, λ h', xp.property⟩)
|
||||
(λ hp, ⟨choice h, λ h, absurd h hp⟩)
|
||||
⟨xp.val, fun h' => xp.property⟩)
|
||||
(fun hp => ⟨choice h, fun h => absurd h hp⟩)
|
||||
|
||||
/- the Hilbert epsilon Function -/
|
||||
|
||||
|
|
@ -1777,30 +1779,30 @@ noncomputable def epsilon {α : Sort u} [h : Nonempty α] (p : α → Prop) : α
|
|||
(strongIndefiniteDescription p h).val
|
||||
|
||||
theorem epsilonSpecAux {α : Sort u} (h : Nonempty α) (p : α → Prop)
|
||||
: Exists (λ y, p y) → p (@epsilon α h p) :=
|
||||
: Exists (fun y => p y) → p (@epsilon α h p) :=
|
||||
(strongIndefiniteDescription p h).property
|
||||
|
||||
theorem epsilonSpec {α : Sort u} {p : α → Prop} (hex : Exists (λ y, p y)) :
|
||||
theorem epsilonSpec {α : Sort u} {p : α → Prop} (hex : Exists (fun y => p y)) :
|
||||
p (@epsilon α (nonemptyOfExists hex) p) :=
|
||||
epsilonSpecAux (nonemptyOfExists hex) p hex
|
||||
|
||||
theorem epsilonSingleton {α : Sort u} (x : α) : @epsilon α ⟨x⟩ (λ y, y = x) = x :=
|
||||
@epsilonSpec α (λ y, y = x) ⟨x, rfl⟩
|
||||
theorem epsilonSingleton {α : Sort u} (x : α) : @epsilon α ⟨x⟩ (fun y => y = x) = x :=
|
||||
@epsilonSpec α (fun y => y = x) ⟨x, rfl⟩
|
||||
|
||||
/- the axiom of choice -/
|
||||
|
||||
theorem axiomOfChoice {α : Sort u} {β : α → Sort v} {r : Π x, β x → Prop} (h : ∀ x, Exists (λ y, r x y)) :
|
||||
Exists (λ (f : Π x, β x), ∀ x, r x (f x)) :=
|
||||
⟨_, λ x, chooseSpec (h x)⟩
|
||||
theorem axiomOfChoice {α : Sort u} {β : α → Sort v} {r : Π x, β x → Prop} (h : ∀ x, Exists (fun y => r x y)) :
|
||||
Exists (fun (f : Π x, β x) => ∀ x, r x (f x)) :=
|
||||
⟨_, fun x => chooseSpec (h x)⟩
|
||||
|
||||
theorem skolem {α : Sort u} {b : α → Sort v} {p : Π x, b x → Prop} :
|
||||
(∀ x, Exists (λ y, p x y)) ↔ Exists (λ (f : Π x, b x), ∀ x, p x (f x)) :=
|
||||
⟨axiomOfChoice, λ ⟨f, hw⟩ x, ⟨f x, hw x⟩⟩
|
||||
(∀ x, Exists (fun y => p x y)) ↔ Exists (fun (f : Π x, b x) => ∀ x, p x (f x)) :=
|
||||
⟨axiomOfChoice, fun ⟨f, hw⟩ (x) => ⟨f x, hw x⟩⟩
|
||||
|
||||
theorem propComplete (a : Prop) : a = True ∨ a = False :=
|
||||
Or.elim (em a)
|
||||
(λ t, Or.inl (eqTrueIntro t))
|
||||
(λ f, Or.inr (eqFalseIntro f))
|
||||
(fun t => Or.inl (eqTrueIntro t))
|
||||
(fun f => Or.inr (eqFalseIntro f))
|
||||
|
||||
-- this supercedes byCases in Decidable
|
||||
theorem byCases {p q : Prop} (hpq : p → q) (hnpq : ¬p → q) : q :=
|
||||
|
|
|
|||
|
|
@ -30,19 +30,19 @@ variables {α : Type u} {β : Type v} {σ : Type w}
|
|||
@[extern cpp inline "lean::mk_empty_array(#2)"]
|
||||
def mkEmpty (c : @& Nat) : Array α :=
|
||||
{ sz := 0,
|
||||
data := λ ⟨x, h⟩, absurd h (Nat.notLtZero x) }
|
||||
data := fun ⟨x, h⟩ => absurd h (Nat.notLtZero x) }
|
||||
|
||||
@[extern cpp inline "lean::array_push(#2, #3)"]
|
||||
def push (a : Array α) (v : α) : Array α :=
|
||||
{ sz := Nat.succ a.sz,
|
||||
data := λ ⟨j, h₁⟩,
|
||||
data := fun ⟨j, h₁⟩ =>
|
||||
if h₂ : j = a.sz then v
|
||||
else a.data ⟨j, Nat.ltOfLeOfNe (Nat.leOfLtSucc h₁) h₂⟩ }
|
||||
|
||||
@[extern cpp inline "lean::mk_array(#2, #3)"]
|
||||
def mkArray {α : Type u} (n : Nat) (v : α) : Array α :=
|
||||
{ sz := n,
|
||||
data := λ _, v}
|
||||
data := fun _ => v}
|
||||
|
||||
theorem szMkArrayEq {α : Type u} (n : Nat) (v : α) : (mkArray n v).sz = n :=
|
||||
rfl
|
||||
|
|
@ -87,7 +87,7 @@ if h : i < a.size then some (a.fget ⟨i, h⟩) else none
|
|||
@[extern cpp inline "lean::array_fset(#2, #3, #4)"]
|
||||
def fset (a : Array α) (i : @& Fin a.size) (v : α) : Array α :=
|
||||
{ sz := a.sz,
|
||||
data := λ j, if h : i = j then v else a.data j }
|
||||
data := fun j => if h : i = j then v else a.data j }
|
||||
|
||||
theorem szFSetEq (a : Array α) (i : Fin a.size) (v : α) : (fset a i v).size = a.size :=
|
||||
rfl
|
||||
|
|
@ -129,7 +129,7 @@ if h : i < a.size then fswapAt a ⟨i, h⟩ v else (v, a)
|
|||
@[extern cpp inline "lean::array_pop(#2)"]
|
||||
def pop (a : Array α) : Array α :=
|
||||
{ sz := Nat.pred a.size,
|
||||
data := λ ⟨j, h⟩, a.fget ⟨j, Nat.ltOfLtOfLe h (Nat.predLe _)⟩ }
|
||||
data := fun ⟨j, h⟩ => a.fget ⟨j, Nat.ltOfLtOfLe h (Nat.predLe _)⟩ }
|
||||
|
||||
-- TODO(Leo): justify termination using wf-rec
|
||||
partial def shrink : Array α → Nat → Array α
|
||||
|
|
@ -150,10 +150,10 @@ variables {m : Type v → Type v} [Monad m]
|
|||
miterateAux a f 0 b
|
||||
|
||||
@[inline] def mfoldl (f : β → α → m β) (b : β) (a : Array α) : m β :=
|
||||
miterate a b (λ _ b a, f a b)
|
||||
miterate a b (fun _ b a => f a b)
|
||||
|
||||
@[inline] def mfoldlFrom (f : β → α → m β) (b : β) (a : Array α) (ini : Nat := 0) : m β :=
|
||||
miterateAux a (λ _ b a, f a b) ini b
|
||||
miterateAux a (fun _ b a => f a b) ini b
|
||||
|
||||
-- TODO(Leo): justify termination using wf-rec
|
||||
@[specialize] partial def miterate₂Aux (a₁ : Array α) (a₂ : Array σ) (f : Π i : Fin a₁.size, α → σ → β → m β) : Nat → β → m β
|
||||
|
|
@ -170,7 +170,7 @@ miterateAux a (λ _ b a, f a b) ini b
|
|||
miterate₂Aux a₁ a₂ f 0 b
|
||||
|
||||
@[inline] def mfoldl₂ (f : β → α → σ → m β) (b : β) (a₁ : Array α) (a₂ : Array σ): m β :=
|
||||
miterate₂ a₁ a₂ b (λ _ a₁ a₂ b, f b a₁ a₂)
|
||||
miterate₂ a₁ a₂ b (fun _ a₁ a₂ b => f b a₁ a₂)
|
||||
|
||||
-- TODO(Leo): justify termination using wf-rec
|
||||
@[specialize] partial def mfindAux (a : Array α) (f : α → m (Option β)) : Nat → m (Option β)
|
||||
|
|
@ -195,7 +195,7 @@ Id.run $ miterateAux a f 0 b
|
|||
Id.run $ miterateAux a f i b
|
||||
|
||||
@[inline] def foldl (f : β → α → β) (b : β) (a : Array α) : β :=
|
||||
iterate a b (λ _ a b, f b a)
|
||||
iterate a b (fun _ a b => f b a)
|
||||
|
||||
@[inline] def foldlFrom (f : β → α → β) (b : β) (a : Array α) (ini : Nat := 0) : β :=
|
||||
Id.run $ mfoldlFrom f b a ini
|
||||
|
|
@ -204,7 +204,7 @@ Id.run $ mfoldlFrom f b a ini
|
|||
Id.run $ miterate₂Aux a₁ a₂ f 0 b
|
||||
|
||||
@[inline] def foldl₂ (f : β → α → σ → β) (b : β) (a₁ : Array α) (a₂ : Array σ) : β :=
|
||||
iterate₂ a₁ a₂ b (λ _ a₁ a₂ b, f b a₁ a₂)
|
||||
iterate₂ a₁ a₂ b (fun _ a₁ a₂ b => f b a₁ a₂)
|
||||
|
||||
@[inline] def find (a : Array α) (f : α → Option β) : Option β :=
|
||||
Id.run $ mfindAux a f 0
|
||||
|
|
@ -226,14 +226,14 @@ variables {m : Type → Type v} [Monad m]
|
|||
anyMAux a p 0
|
||||
|
||||
@[inline] def allM (a : Array α) (p : α → m Bool) : m Bool :=
|
||||
not <$> anyM a (λ v, not <$> p v)
|
||||
not <$> anyM a (fun v => not <$> p v)
|
||||
end
|
||||
|
||||
@[inline] def any (a : Array α) (p : α → Bool) : Bool :=
|
||||
Id.run $ anyM a p
|
||||
|
||||
@[inline] def all (a : Array α) (p : α → Bool) : Bool :=
|
||||
!any a (λ v, !p v)
|
||||
!any a (fun v => !p v)
|
||||
|
||||
@[specialize] private def revIterateAux (a : Array α) (f : Π i : Fin a.size, α → β → β) : Π (i : Nat), i ≤ a.size → β → β
|
||||
| 0 h b := b
|
||||
|
|
@ -245,7 +245,7 @@ Id.run $ anyM a p
|
|||
revIterateAux a f a.size (Nat.leRefl _) b
|
||||
|
||||
@[inline] def revFoldl (a : Array α) (b : β) (f : α → β → β) : β :=
|
||||
revIterate a b (λ _, f)
|
||||
revIterate a b (fun _ => f)
|
||||
|
||||
def toList (a : Array α) : List α :=
|
||||
a.revFoldl [] List.cons
|
||||
|
|
@ -271,16 +271,16 @@ variables {m : Type v → Type v} [Monad m]
|
|||
pure (unsafeCast a)
|
||||
|
||||
@[inline] unsafe partial def ummap (f : α → m β) (as : Array α) : m (Array β) :=
|
||||
ummapAux (λ i a, f a) 0 as
|
||||
ummapAux (fun i a => f a) 0 as
|
||||
|
||||
@[inline] unsafe partial def ummapIdx (f : Nat → α → m β) (as : Array α) : m (Array β) :=
|
||||
ummapAux f 0 as
|
||||
|
||||
@[implementedBy Array.ummap] def mmap (f : α → m β) (as : Array α) : m (Array β) :=
|
||||
as.mfoldl (λ bs a, do b ← f a; pure (bs.push b)) (mkEmpty as.size)
|
||||
as.mfoldl (fun bs a => do b ← f a; pure (bs.push b)) (mkEmpty as.size)
|
||||
|
||||
@[implementedBy Array.ummapIdx] def mmapIdx (f : Nat → α → m β) (as : Array α) : m (Array β) :=
|
||||
as.miterate (mkEmpty as.size) (λ i a bs, do b ← f i.val a; pure (bs.push b))
|
||||
as.miterate (mkEmpty as.size) (fun i a bs => do b ← f i.val a; pure (bs.push b))
|
||||
end
|
||||
|
||||
@[inline] def modify [Inhabited α] (a : Array α) (i : Nat) (f : α → α) : Array α :=
|
||||
|
|
@ -331,7 +331,7 @@ if h : e ≤ a.size then extractAux a b e h r
|
|||
else r
|
||||
|
||||
protected def append (a : Array α) (b : Array α) : Array α :=
|
||||
b.foldl (λ a v, a.push v) a
|
||||
b.foldl (fun a v => a.push v) a
|
||||
|
||||
instance : HasAppend (Array α) := ⟨Array.append⟩
|
||||
|
||||
|
|
@ -354,7 +354,7 @@ else
|
|||
false
|
||||
|
||||
instance [HasBeq α] : HasBeq (Array α) :=
|
||||
⟨λ a b, isEqv a b HasBeq.beq⟩
|
||||
⟨fun a b => isEqv a b HasBeq.beq⟩
|
||||
|
||||
-- TODO(Leo): justify termination using wf-rec, and use `fswap`
|
||||
partial def reverseAux : Array α → Nat → Array α
|
||||
|
|
|
|||
|
|
@ -63,4 +63,4 @@ def List.toByteArray (bs : List UInt8) : ByteArray :=
|
|||
bs.toByteArrayAux ByteArray.empty
|
||||
|
||||
instance : HasToString ByteArray :=
|
||||
⟨λ bs, bs.toList.toString⟩
|
||||
⟨fun bs => bs.toList.toString⟩
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ structure Char :=
|
|||
(val : UInt32) (valid : isValidChar val)
|
||||
|
||||
instance : HasSizeof Char :=
|
||||
⟨λ c, c.val.toNat⟩
|
||||
⟨fun c => c.val.toNat⟩
|
||||
|
||||
namespace Char
|
||||
def utf8Size (c : Char) : UInt32 :=
|
||||
|
|
@ -57,13 +57,13 @@ theorem veqOfEq : ∀ {c d : Char}, c = d → c.val = d.val
|
|||
| _ _ rfl := rfl
|
||||
|
||||
theorem neOfVne {c d : Char} (h : c.val ≠ d.val) : c ≠ d :=
|
||||
λ h', absurd (veqOfEq h') h
|
||||
fun h' => absurd (veqOfEq h') h
|
||||
|
||||
theorem vneOfNe {c d : Char} (h : c ≠ d) : c.val ≠ d.val :=
|
||||
λ h', absurd (eqOfVeq h') h
|
||||
fun h' => absurd (eqOfVeq h') h
|
||||
|
||||
instance : DecidableEq Char :=
|
||||
{decEq := λ i j, decidableOfDecidableOfIff
|
||||
{decEq := fun i j => decidableOfDecidableOfIff
|
||||
(decEq i.val j.val) ⟨Char.eqOfVeq, Char.veqOfEq⟩}
|
||||
|
||||
instance : Inhabited Char :=
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ variables {α : Type u}
|
|||
open List
|
||||
|
||||
def ofList (l : List α) : DList α :=
|
||||
⟨append l, λ t, (appendNil l).symm ▸ rfl⟩
|
||||
⟨append l, fun t => (appendNil l).symm ▸ rfl⟩
|
||||
|
||||
def empty : DList α :=
|
||||
⟨id, λ t, rfl⟩
|
||||
⟨id, fun t => rfl⟩
|
||||
|
||||
instance : HasEmptyc (DList α) :=
|
||||
⟨DList.empty⟩
|
||||
|
|
@ -33,22 +33,25 @@ def toList : DList α → List α
|
|||
| ⟨f, h⟩ := f []
|
||||
|
||||
def singleton (a : α) : DList α :=
|
||||
⟨λ t, a :: t, λ t, rfl⟩
|
||||
⟨fun t => a :: t,
|
||||
fun t => rfl⟩
|
||||
|
||||
def cons : α → DList α → DList α
|
||||
| a ⟨f, h⟩ := ⟨λ t, a :: f t, λ t,
|
||||
| a ⟨f, h⟩ := ⟨fun t => a :: f t,
|
||||
fun t =>
|
||||
show a :: f t = a :: f [] ++ t, from
|
||||
have h₁ : a :: f t = a :: (f nil ++ t), from h t ▸ rfl,
|
||||
have h₂ : a :: (f nil ++ t) = a :: f nil ++ t, from (consAppend _ _ _).symm,
|
||||
Eq.trans h₁ h₂⟩
|
||||
|
||||
def append : DList α → DList α → DList α
|
||||
| ⟨f, h₁⟩ ⟨g, h₂⟩ := ⟨f ∘ g, λ t,
|
||||
| ⟨f, h₁⟩ ⟨g, h₂⟩ := ⟨f ∘ g, fun t =>
|
||||
show f (g t) = (f (g [])) ++ t, from
|
||||
(h₁ (g [])).symm ▸ (appendAssoc (f []) (g []) t).symm ▸ h₂ t ▸ h₁ (g t) ▸ rfl⟩
|
||||
|
||||
def push : DList α → α → DList α
|
||||
| ⟨f, h⟩ a := ⟨λ t, f (a :: t), λ t, (h (a::t)).symm ▸ (h [a]).symm ▸ (appendAssoc (f []) [a] t).symm ▸ rfl⟩
|
||||
| ⟨f, h⟩ a := ⟨fun t => f (a :: t),
|
||||
fun t => (h (a::t)).symm ▸ (h [a]).symm ▸ (appendAssoc (f []) [a] t).symm ▸ rfl⟩
|
||||
|
||||
instance : HasAppend (DList α) :=
|
||||
⟨DList.append⟩
|
||||
|
|
|
|||
|
|
@ -85,10 +85,10 @@ theorem veqOfEq : ∀ {i j : Fin n}, i = j → (val i) = (val j)
|
|||
| ⟨iv, ilt⟩ .(_) rfl := rfl
|
||||
|
||||
theorem neOfVne {i j : Fin n} (h : val i ≠ val j) : i ≠ j :=
|
||||
λ h', absurd (veqOfEq h') h
|
||||
fun h' => absurd (veqOfEq h') h
|
||||
|
||||
theorem vneOfNe {i j : Fin n} (h : i ≠ j) : val i ≠ val j :=
|
||||
λ h', absurd (eqOfVeq h') h
|
||||
fun h' => absurd (eqOfVeq h') h
|
||||
|
||||
theorem modnLt : ∀ {m : Nat} (i : Fin n), m > 0 → (i %ₙ m).val < m
|
||||
| m ⟨a, h⟩ hp := Nat.ltOfLeOfLt (modLe _ _) (modLt _ hp)
|
||||
|
|
@ -98,5 +98,5 @@ end Fin
|
|||
open Fin
|
||||
|
||||
instance (n : Nat) : DecidableEq (Fin n) :=
|
||||
{decEq := λ i j, decidableOfDecidableOfIff
|
||||
{decEq := fun i j => decidableOfDecidableOfIff
|
||||
(decEq i.val j.val) ⟨eqOfVeq, veqOfEq⟩}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ let ⟨i, h⟩ := mkIdx data.property (hashFn a);
|
|||
data.update i (AssocList.cons a b (data.val.uget i h)) h
|
||||
|
||||
@[inline] def mfoldBuckets {δ : Type w} {m : Type w → Type w} [Monad m] (data : HashMapBucket α β) (d : δ) (f : δ → α → β → m δ) : m δ :=
|
||||
data.val.mfoldl (λ d b, b.mfoldl f d) d
|
||||
data.val.mfoldl (fun d b => b.mfoldl f d) d
|
||||
|
||||
@[inline] def foldBuckets {δ : Type w} (data : HashMapBucket α β) (d : δ) (f : δ → α → β → δ) : δ :=
|
||||
Id.run $ mfoldBuckets data d f
|
||||
|
|
|
|||
|
|
@ -84,12 +84,12 @@ protected def decEq (a b : @& Int) : Decidable (a = b) :=
|
|||
match a, b with
|
||||
| ofNat a, ofNat b := match decEq a b with
|
||||
| isTrue h := isTrue $ h ▸ rfl
|
||||
| isFalse h := isFalse $ λ h', Int.noConfusion h' (λ h', absurd h' h)
|
||||
| isFalse h := isFalse $ fun h' => Int.noConfusion h' (fun h' => absurd h' h)
|
||||
| negSucc a, negSucc b := match decEq a b with
|
||||
| isTrue h := isTrue $ h ▸ rfl
|
||||
| isFalse h := isFalse $ λ h', Int.noConfusion h' (λ h', absurd h' h)
|
||||
| ofNat a, negSucc b := isFalse $ λ h, Int.noConfusion h
|
||||
| negSucc a, ofNat b := isFalse $ λ h, Int.noConfusion h
|
||||
| isFalse h := isFalse $ fun h' => Int.noConfusion h' (fun h' => absurd h' h)
|
||||
| ofNat a, negSucc b := isFalse $ fun h => Int.noConfusion h
|
||||
| negSucc a, ofNat b := isFalse $ fun h => Int.noConfusion h
|
||||
|
||||
instance Int.DecidableEq : DecidableEq Int :=
|
||||
{decEq := Int.decEq}
|
||||
|
|
@ -98,7 +98,7 @@ instance Int.DecidableEq : DecidableEq Int :=
|
|||
private def decNonneg (m : @& Int) : Decidable (NonNeg m) :=
|
||||
match m with
|
||||
| ofNat m := isTrue $ NonNeg.mk m
|
||||
| negSucc m := isFalse $ λ h, match h with end
|
||||
| negSucc m := isFalse $ fun h => match h with end
|
||||
|
||||
@[extern cpp "lean::int_dec_le"]
|
||||
instance decLe (a b : @& Int) : Decidable (a ≤ b) :=
|
||||
|
|
|
|||
|
|
@ -18,15 +18,15 @@ namespace List
|
|||
|
||||
protected def hasDecEq [DecidableEq α] : Π a b : List α, Decidable (a = b)
|
||||
| [] [] := isTrue rfl
|
||||
| (a::as) [] := isFalse (λ h, List.noConfusion h)
|
||||
| [] (b::bs) := isFalse (λ h, List.noConfusion h)
|
||||
| (a::as) [] := isFalse (fun h => List.noConfusion h)
|
||||
| [] (b::bs) := isFalse (fun h => List.noConfusion h)
|
||||
| (a::as) (b::bs) :=
|
||||
match decEq a b with
|
||||
| isTrue hab :=
|
||||
match hasDecEq as bs with
|
||||
| isTrue habs := isTrue (Eq.subst hab (Eq.subst habs rfl))
|
||||
| isFalse nabs := isFalse (λ h, List.noConfusion h (λ _ habs, absurd habs nabs))
|
||||
| isFalse nab := isFalse (λ h, List.noConfusion h (λ hab _, absurd hab nab))
|
||||
| isFalse nabs := isFalse (fun h => List.noConfusion h (fun _ habs => absurd habs nabs))
|
||||
| isFalse nab := isFalse (fun h => List.noConfusion h (fun hab _ => absurd hab nab))
|
||||
|
||||
instance [DecidableEq α] : DecidableEq (List α) :=
|
||||
{decEq := List.hasDecEq}
|
||||
|
|
@ -36,7 +36,7 @@ def reverseAux : List α → List α → List α
|
|||
| (a::l) r := reverseAux l (a::r)
|
||||
|
||||
def reverse : List α → List α :=
|
||||
λ l, reverseAux l []
|
||||
fun l => reverseAux l []
|
||||
|
||||
protected def append (as bs : List α) : List α :=
|
||||
reverseAux as.reverse bs
|
||||
|
|
@ -62,7 +62,7 @@ theorem reverseAuxReverseAux : ∀ (as bs cs : List α), reverseAux (reverseAux
|
|||
| (a::as) bs cs :=
|
||||
Eq.trans
|
||||
(reverseAuxReverseAux as (a::bs) cs)
|
||||
(congrArg (λ b, reverseAux bs b) (reverseAuxReverseAux as [a] cs).symm)
|
||||
(congrArg (fun b => reverseAux bs b) (reverseAuxReverseAux as [a] cs).symm)
|
||||
|
||||
theorem consAppend (a : α) (as bs : List α) : (a::as) ++ bs = a::(as ++ bs) :=
|
||||
reverseAuxReverseAux as [a] bs
|
||||
|
|
@ -71,9 +71,9 @@ theorem appendAssoc : ∀ (as bs cs : List α), (as ++ bs) ++ cs = as ++ (bs ++
|
|||
| [] bs cs := rfl
|
||||
| (a::as) bs cs :=
|
||||
show ((a::as) ++ bs) ++ cs = (a::as) ++ (bs ++ cs), from
|
||||
have h₁ : ((a::as) ++ bs) ++ cs = a::(as++bs) ++ cs, from congrArg (λ ds, ds ++ cs) (consAppend a as bs),
|
||||
have h₁ : ((a::as) ++ bs) ++ cs = a::(as++bs) ++ cs, from congrArg (fun ds => ds ++ cs) (consAppend a as bs),
|
||||
have h₂ : a::(as++bs) ++ cs = a::((as++bs) ++ cs), from consAppend a (as++bs) cs,
|
||||
have h₃ : a::((as++bs) ++ cs) = a::(as ++ (bs ++ cs)), from congrArg (λ as, a::as) (appendAssoc as bs cs),
|
||||
have h₃ : a::((as++bs) ++ cs) = a::(as ++ (bs ++ cs)), from congrArg (fun as => a::as) (appendAssoc as bs cs),
|
||||
have h₄ : a::(as ++ (bs ++ cs)) = (a::as ++ (bs ++ cs)), from (consAppend a as (bs++cs)).symm,
|
||||
Eq.trans (Eq.trans (Eq.trans h₁ h₂) h₃) h₄
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ theorem notMem : ∀ {a b : α} {bs : List α}, a ≠ b → ¬ a ∈ bs → ¬ a
|
|||
| _ _ _ _ h₁ (Mem.inTail _ h₂) := absurd h₂ h₁
|
||||
|
||||
instance decidableMem [DecidableEq α] (a : α) : ∀ (l : List α), Decidable (a ∈ l)
|
||||
| [] := isFalse (λ h, match h with end)
|
||||
| [] := isFalse (fun h => match h with end)
|
||||
| (b::bs) :=
|
||||
if h₁ : a = b then isTrue (h₁.symm ▸ Mem.eqHead b bs)
|
||||
else match decidableMem bs with
|
||||
|
|
@ -213,7 +213,7 @@ def lookup [HasBeq α] : α → List (α × β) → Option β
|
|||
| false := lookup a es
|
||||
|
||||
def removeAll [HasBeq α] (xs ys : List α) : List α :=
|
||||
xs.filter (λ x, ys.notElem x)
|
||||
xs.filter (fun x => ys.notElem x)
|
||||
|
||||
def drop : Nat → List α → List α
|
||||
| 0 a := a
|
||||
|
|
@ -236,17 +236,17 @@ def take : Nat → List α → List α
|
|||
@[specialize] def foldr1 (f : α → α → α) : Π (xs : List α), xs ≠ [] → α
|
||||
| [] h := absurd rfl h
|
||||
| [a] _ := a
|
||||
| (a :: as@(_::_)) _ := f a (foldr1 as (λ h, List.noConfusion h))
|
||||
| (a :: as@(_::_)) _ := f a (foldr1 as (fun h => List.noConfusion h))
|
||||
|
||||
@[specialize] def foldr1Opt (f : α → α → α) : List α → Option α
|
||||
| [] := none
|
||||
| (a :: as) := some $ foldr1 f (a :: as) (λ h, List.noConfusion h)
|
||||
| (a :: as) := some $ foldr1 f (a :: as) (fun h => List.noConfusion h)
|
||||
|
||||
@[inline] def any (l : List α) (p : α → Bool) : Bool :=
|
||||
foldr (λ a r, p a || r) false l
|
||||
foldr (fun a r => p a || r) false l
|
||||
|
||||
@[inline] def all (l : List α) (p : α → Bool) : Bool :=
|
||||
foldr (λ a r, p a && r) true l
|
||||
foldr (fun a r => p a && r) true l
|
||||
|
||||
def or (bs : List Bool) : Bool := bs.any id
|
||||
|
||||
|
|
@ -270,7 +270,7 @@ instance [DecidableEq α] : HasInsert α (List α) :=
|
|||
⟨List.insert⟩
|
||||
|
||||
def replicate (n : Nat) (a : α) : List α :=
|
||||
n.repeat (λ xs, a :: xs) []
|
||||
n.repeat (fun xs => a :: xs) []
|
||||
|
||||
def rangeAux : Nat → List Nat → List Nat
|
||||
| 0 ns := ns
|
||||
|
|
@ -292,11 +292,11 @@ def enum : List α → List (Nat × α) := enumFrom 0
|
|||
def getLastOfNonNil : Π (as : List α), as ≠ [] → α
|
||||
| [] h := absurd rfl h
|
||||
| [a] h := a
|
||||
| (a::b::as) h := getLastOfNonNil (b::as) (λ h, List.noConfusion h)
|
||||
| (a::b::as) h := getLastOfNonNil (b::as) (fun h => List.noConfusion h)
|
||||
|
||||
def getLast [Inhabited α] : List α → α
|
||||
| [] := arbitrary α
|
||||
| (a::as) := getLastOfNonNil (a::as) (λ h, List.noConfusion h)
|
||||
| (a::as) := getLastOfNonNil (a::as) (fun h => List.noConfusion h)
|
||||
|
||||
def init : List α → List α
|
||||
| [] := []
|
||||
|
|
@ -326,21 +326,21 @@ instance [HasLess α] : HasLess (List α) :=
|
|||
⟨List.Less⟩
|
||||
|
||||
instance hasDecidableLt [HasLess α] [h : DecidableRel HasLess.Less] : Π l₁ l₂ : List α, Decidable (l₁ < l₂)
|
||||
| [] [] := isFalse (λ h, match h with end)
|
||||
| [] [] := isFalse (fun h => match h with end)
|
||||
| [] (b::bs) := isTrue (Less.nil _ _)
|
||||
| (a::as) [] := isFalse (λ h, match h with end)
|
||||
| (a::as) [] := isFalse (fun h => match h with end)
|
||||
| (a::as) (b::bs) :=
|
||||
match h a b with
|
||||
| isTrue h₁ := isTrue (Less.head _ _ h₁)
|
||||
| isFalse h₁ :=
|
||||
match h b a with
|
||||
| isTrue h₂ := isFalse (λ h, match h with
|
||||
| isTrue h₂ := isFalse (fun h => match h with
|
||||
| Less.head _ _ h₁' := absurd h₁' h₁
|
||||
| Less.tail _ h₂' _ := absurd h₂ h₂')
|
||||
| isFalse h₂ :=
|
||||
match hasDecidableLt as bs with
|
||||
| isTrue h₃ := isTrue (Less.tail h₁ h₂ h₃)
|
||||
| isFalse h₃ := isFalse (λ h, match h with
|
||||
| isFalse h₃ := isFalse (fun h => match h with
|
||||
| Less.head _ _ h₁' := absurd h₁' h₁
|
||||
| Less.tail _ _ h₃' := absurd h₃' h₃)
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ instance [HasLess α] : HasLessEq (List α) :=
|
|||
⟨List.LessEq⟩
|
||||
|
||||
instance hasDecidableLe [HasLess α] [h : DecidableRel (HasLess.Less : α → α → Prop)] : Π l₁ l₂ : List α, Decidable (l₁ ≤ l₂) :=
|
||||
λ a b, Not.Decidable
|
||||
fun a b => Not.Decidable
|
||||
|
||||
/-- `isPrefixOf l₁ l₂` returns `true` Iff `l₁` is a prefix of `l₂`. -/
|
||||
def isPrefixOf [HasBeq α] : List α → List α → Bool
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ theorem neOfBeqEqFf : ∀ {n m : Nat}, beq n m = false → n ≠ m
|
|||
| (succ n) (succ m) h₁ h₂ :=
|
||||
have beq n m = false, from h₁,
|
||||
have n ≠ m, from neOfBeqEqFf this,
|
||||
Nat.noConfusion h₂ (λ h₂, absurd h₂ this)
|
||||
Nat.noConfusion h₂ (fun h₂ => absurd h₂ this)
|
||||
|
||||
@[extern cpp "lean::nat_dec_eq"]
|
||||
protected def decEq (n m : @& Nat) : Decidable (n = m) :=
|
||||
|
|
@ -98,7 +98,7 @@ foldAux f n n a
|
|||
anyAux f n n
|
||||
|
||||
@[inline] def all (f : Nat → Bool) (n : Nat) : Bool :=
|
||||
!any (λ i, !f i) n
|
||||
!any (fun i => !f i) n
|
||||
|
||||
@[specialize] def repeatAux {α : Type u} (f : α → α) : Nat → α → α
|
||||
| 0 a := a
|
||||
|
|
@ -200,7 +200,7 @@ protected theorem leftDistrib : ∀ (n m k : Nat), n * (m + k) = n * m + n * k
|
|||
have h₁ : succ n * (m + k) = n * (m + k) + (m + k), from succMul _ _,
|
||||
have h₂ : n * (m + k) + (m + k) = (n * m + n * k) + (m + k), from leftDistrib n m k ▸ rfl,
|
||||
have h₃ : (n * m + n * k) + (m + k) = n * m + (n * k + (m + k)), from Nat.addAssoc _ _ _,
|
||||
have h₄ : n * m + (n * k + (m + k)) = n * m + (m + (n * k + k)), from congrArg (λ x, n*m + x) (Nat.addLeftComm _ _ _),
|
||||
have h₄ : n * m + (n * k + (m + k)) = n * m + (m + (n * k + k)), from congrArg (fun x => n*m + x) (Nat.addLeftComm _ _ _),
|
||||
have h₅ : n * m + (m + (n * k + k)) = (n * m + m) + (n * k + k), from (Nat.addAssoc _ _ _).symm,
|
||||
have h₆ : (n * m + m) + (n * k + k) = (n * m + m) + succ n * k, from succMul n k ▸ rfl,
|
||||
have h₇ : (n * m + m) + succ n * k = succ n * m + succ n * k, from succMul n m ▸ rfl,
|
||||
|
|
@ -289,8 +289,8 @@ protected theorem eqOrLtOfLe : ∀ {n m: Nat}, n ≤ m → n = m ∨ n < m
|
|||
have n ≤ m, from h,
|
||||
have n = m ∨ n < m, from eqOrLtOfLe this,
|
||||
Or.elim this
|
||||
(λ h, Or.inl $ congrArg succ h)
|
||||
(λ h, Or.inr $ succLtSucc h)
|
||||
(fun h => Or.inl $ congrArg succ h)
|
||||
(fun h => Or.inr $ succLtSucc h)
|
||||
|
||||
theorem ltSuccOfLe {n m : Nat} : n ≤ m → n < succ m :=
|
||||
succLeSucc
|
||||
|
|
@ -301,10 +301,10 @@ rfl
|
|||
theorem succSubSuccEqSub (n m : Nat) : succ n - succ m = n - m :=
|
||||
Nat.recOn m
|
||||
(show succ n - succ zero = n - zero, from (Eq.refl (succ n - succ zero)))
|
||||
(λ m, congrArg pred)
|
||||
(fun m => congrArg pred)
|
||||
|
||||
theorem notSuccLeSelf : ∀ n : Nat, ¬succ n ≤ n :=
|
||||
λ n, Nat.rec (notSuccLeZero 0) (λ a b c, b (leOfSuccLeSucc c)) n
|
||||
fun n => Nat.rec (notSuccLeZero 0) (fun a b c => b (leOfSuccLeSucc c)) n
|
||||
|
||||
protected theorem ltIrrefl (n : Nat) : ¬n < n :=
|
||||
notSuccLeSelf n
|
||||
|
|
@ -328,7 +328,7 @@ theorem predLt : ∀ {n : Nat}, n ≠ 0 → pred n < n
|
|||
| (succ n) h := ltSuccOfLe (Nat.leRefl _)
|
||||
|
||||
theorem subLe (n m : Nat) : n - m ≤ n :=
|
||||
Nat.recOn m (Nat.leRefl (n - 0)) (λ m, Nat.leTrans (predLe (n - m)))
|
||||
Nat.recOn m (Nat.leRefl (n - 0)) (fun m => Nat.leTrans (predLe (n - m)))
|
||||
|
||||
theorem subLt : ∀ {n m : Nat}, 0 < n → 0 < m → n - m < n
|
||||
| 0 m h1 h2 := absurd h1 (Nat.ltIrrefl 0)
|
||||
|
|
@ -391,7 +391,7 @@ protected theorem ltOrGe : ∀ (n m : Nat), n < m ∨ n ≥ m
|
|||
|
||||
protected theorem leTotal (m n : Nat) : m ≤ n ∨ n ≤ m :=
|
||||
Or.elim (Nat.ltOrGe m n)
|
||||
(λ h, Or.inl (Nat.leOfLt h))
|
||||
(fun h => Or.inl (Nat.leOfLt h))
|
||||
Or.inr
|
||||
|
||||
protected theorem ltOfLeAndNe {m n : Nat} (h1 : m ≤ n) : m ≠ n → m < n :=
|
||||
|
|
@ -414,8 +414,8 @@ h
|
|||
|
||||
theorem ltOrEqOrLeSucc {m n : Nat} (h : m ≤ succ n) : m ≤ n ∨ m = succ n :=
|
||||
Decidable.byCases
|
||||
(λ h' : m = succ n, Or.inr h')
|
||||
(λ h' : m ≠ succ n,
|
||||
(fun (h' : m = succ n) => Or.inr h')
|
||||
(fun (h' : m ≠ succ n) =>
|
||||
have m < succ n, from Nat.ltOfLeAndNe h h',
|
||||
have succ m ≤ succ n, from succLeOfLt this,
|
||||
Or.inl (leOfSuccLeSucc this))
|
||||
|
|
@ -427,13 +427,13 @@ theorem leAddRight : ∀ (n k : Nat), n ≤ n + k
|
|||
theorem leAddLeft (n m : Nat): n ≤ m + n :=
|
||||
Nat.addComm n m ▸ leAddRight n m
|
||||
|
||||
theorem le.dest : ∀ {n m : Nat}, n ≤ m → Exists (λ k, n + k = m)
|
||||
theorem le.dest : ∀ {n m : Nat}, n ≤ m → Exists (fun k => n + k = m)
|
||||
| zero zero h := ⟨0, rfl⟩
|
||||
| zero (succ n) h := ⟨succ n, show 0 + succ n = succ n, from (Nat.addComm 0 (succ n)).symm ▸ rfl⟩
|
||||
| (succ n) zero h := Bool.noConfusion h
|
||||
| (succ n) (succ m) h :=
|
||||
have n ≤ m, from h,
|
||||
have Exists (λ k, n + k = m), from le.dest this,
|
||||
have Exists (fun k => n + k = m), from le.dest this,
|
||||
match this with
|
||||
| ⟨k, h⟩ := ⟨k, show succ n + k = succ m, from ((succAdd n k).symm ▸ h ▸ rfl)⟩
|
||||
|
||||
|
|
@ -441,19 +441,19 @@ theorem le.intro {n m k : Nat} (h : n + k = m) : n ≤ m :=
|
|||
h ▸ leAddRight n k
|
||||
|
||||
protected theorem notLeOfGt {n m : Nat} (h : n > m) : ¬ n ≤ m :=
|
||||
λ h₁, Or.elim (Nat.ltOrGe n m)
|
||||
(λ h₂, absurd (Nat.ltTrans h h₂) (Nat.ltIrrefl _))
|
||||
(λ h₂, have Heq : n = m, from Nat.leAntisymm h₁ h₂, absurd (@Eq.subst _ _ _ _ Heq h) (Nat.ltIrrefl m))
|
||||
fun h₁ => Or.elim (Nat.ltOrGe n m)
|
||||
(fun h₂ => absurd (Nat.ltTrans h h₂) (Nat.ltIrrefl _))
|
||||
(fun h₂ => have Heq : n = m, from Nat.leAntisymm h₁ h₂, absurd (@Eq.subst _ _ _ _ Heq h) (Nat.ltIrrefl m))
|
||||
|
||||
theorem gtOfNotLe {n m : Nat} (h : ¬ n ≤ m) : n > m :=
|
||||
Or.elim (Nat.ltOrGe m n)
|
||||
(λ h₁, h₁)
|
||||
(λ h₁, absurd h₁ h)
|
||||
(fun h₁ => h₁)
|
||||
(fun h₁ => absurd h₁ h)
|
||||
|
||||
protected theorem ltOfLeOfNe {n m : Nat} (h₁ : n ≤ m) (h₂ : n ≠ m) : n < m :=
|
||||
Or.elim (Nat.ltOrGe n m)
|
||||
(λ h₃, h₃)
|
||||
(λ h₃, absurd (Nat.leAntisymm h₁ h₃) h₂)
|
||||
(fun h₃ => h₃)
|
||||
(fun h₃ => absurd (Nat.leAntisymm h₁ h₃) h₂)
|
||||
|
||||
protected theorem addLeAddLeft {n m : Nat} (h : n ≤ m) (k : Nat) : k + n ≤ k + m :=
|
||||
match le.dest h with
|
||||
|
|
@ -466,7 +466,7 @@ protected theorem addLeAddRight {n m : Nat} (h : n ≤ m) (k : Nat) : n + k ≤
|
|||
have h₁ : n + k = k + n, from Nat.addComm _ _,
|
||||
have h₂ : k + n ≤ k + m, from Nat.addLeAddLeft h k,
|
||||
have h₃ : k + m = m + k, from Nat.addComm _ _,
|
||||
transRelLeft (λ a b, a ≤ b) (transRelRight (λ a b, a ≤ b) h₁ h₂) h₃
|
||||
transRelLeft (fun a b => a ≤ b) (transRelRight (fun a b => a ≤ b) h₁ h₂) h₃
|
||||
|
||||
protected theorem addLtAddLeft {n m : Nat} (h : n < m) (k : Nat) : k + n < k + m :=
|
||||
ltOfSuccLe (addSucc k n ▸ Nat.addLeAddLeft (succLeOfLt h) k)
|
||||
|
|
@ -492,13 +492,13 @@ theorem natZeroEqZero : Nat.zero = 0 :=
|
|||
rfl
|
||||
|
||||
protected theorem oneNeZero : 1 ≠ (0 : Nat) :=
|
||||
λ h, Nat.noConfusion h
|
||||
fun h => Nat.noConfusion h
|
||||
|
||||
protected theorem zeroNeOne : 0 ≠ (1 : Nat) :=
|
||||
λ h, Nat.noConfusion h
|
||||
fun h => Nat.noConfusion h
|
||||
|
||||
theorem succNeZero (n : Nat) : succ n ≠ 0 :=
|
||||
λ h, Nat.noConfusion h
|
||||
fun h => Nat.noConfusion h
|
||||
|
||||
protected theorem bit0SuccEq (n : Nat) : bit0 (succ n) = succ (succ (bit0 n)) :=
|
||||
show succ (succ n + n) = succ (succ (n + n)), from
|
||||
|
|
@ -509,7 +509,7 @@ protected theorem zeroLtBit0 : ∀ {n : Nat}, n ≠ 0 → 0 < bit0 n
|
|||
| (succ n) h :=
|
||||
have h₁ : 0 < succ (succ (bit0 n)), from zeroLtSucc _,
|
||||
have h₂ : succ (succ (bit0 n)) = bit0 (succ n), from (Nat.bit0SuccEq n).symm,
|
||||
transRelLeft (λ a b, a < b) h₁ h₂
|
||||
transRelLeft (fun a b => a < b) h₁ h₂
|
||||
|
||||
protected theorem zeroLtBit1 (n : Nat) : 0 < bit1 n :=
|
||||
zeroLtSucc _
|
||||
|
|
@ -519,11 +519,11 @@ protected theorem bit0NeZero : ∀ {n : Nat}, n ≠ 0 → bit0 n ≠ 0
|
|||
| (n+1) h :=
|
||||
suffices (n+1) + (n+1) ≠ 0, from this,
|
||||
suffices succ ((n+1) + n) ≠ 0, from this,
|
||||
λ h, Nat.noConfusion h
|
||||
fun h => Nat.noConfusion h
|
||||
|
||||
protected theorem bit1NeZero (n : Nat) : bit1 n ≠ 0 :=
|
||||
show succ (n + n) ≠ 0, from
|
||||
λ h, Nat.noConfusion h
|
||||
fun h => Nat.noConfusion h
|
||||
|
||||
protected theorem bit1EqSuccBit0 (n : Nat) : bit1 n = succ (bit0 n) :=
|
||||
rfl
|
||||
|
|
@ -533,20 +533,20 @@ Eq.trans (Nat.bit1EqSuccBit0 (succ n)) (congrArg succ (Nat.bit0SuccEq n))
|
|||
|
||||
protected theorem bit1NeOne : ∀ {n : Nat}, n ≠ 0 → bit1 n ≠ 1
|
||||
| 0 h h1 := absurd rfl h
|
||||
| (n+1) h h1 := Nat.noConfusion h1 (λ h2, absurd h2 (succNeZero _))
|
||||
| (n+1) h h1 := Nat.noConfusion h1 (fun h2 => absurd h2 (succNeZero _))
|
||||
|
||||
protected theorem bit0NeOne : ∀ n : Nat, bit0 n ≠ 1
|
||||
| 0 h := absurd h (Ne.symm Nat.oneNeZero)
|
||||
| (n+1) h :=
|
||||
have h1 : succ (succ (n + n)) = 1, from succAdd n n ▸ h,
|
||||
Nat.noConfusion h1
|
||||
(λ h2, absurd h2 (succNeZero (n + n)))
|
||||
(fun h2 => absurd h2 (succNeZero (n + n)))
|
||||
|
||||
protected theorem addSelfNeOne : ∀ (n : Nat), n + n ≠ 1
|
||||
| 0 h := Nat.noConfusion h
|
||||
| (n+1) h :=
|
||||
have h1 : succ (succ (n + n)) = 1, from succAdd n n ▸ h,
|
||||
Nat.noConfusion h1 (λ h2, absurd h2 (Nat.succNeZero (n + n)))
|
||||
Nat.noConfusion h1 (fun h2 => absurd h2 (Nat.succNeZero (n + n)))
|
||||
|
||||
protected theorem bit1NeBit0 : ∀ (n m : Nat), bit1 n ≠ bit0 m
|
||||
| 0 m h := absurd h (Ne.symm (Nat.addSelfNeOne m))
|
||||
|
|
@ -557,11 +557,11 @@ protected theorem bit1NeBit0 : ∀ (n m : Nat), bit1 n ≠ bit0 m
|
|||
have h1 : succ (succ (bit1 n)) = succ (succ (bit0 m)), from
|
||||
Nat.bit0SuccEq m ▸ Nat.bit1SuccEq n ▸ h,
|
||||
have h2 : bit1 n = bit0 m, from
|
||||
Nat.noConfusion h1 (λ h2', Nat.noConfusion h2' (λ h2'', h2'')),
|
||||
Nat.noConfusion h1 (fun h2' => Nat.noConfusion h2' (fun h2'' => h2'')),
|
||||
absurd h2 (bit1NeBit0 n m)
|
||||
|
||||
protected theorem bit0NeBit1 : ∀ (n m : Nat), bit0 n ≠ bit1 m :=
|
||||
λ n m : Nat, Ne.symm (Nat.bit1NeBit0 m n)
|
||||
fun n m => Ne.symm (Nat.bit1NeBit0 m n)
|
||||
|
||||
protected theorem bit0Inj : ∀ {n m : Nat}, bit0 n = bit0 m → n = m
|
||||
| 0 0 h := rfl
|
||||
|
|
@ -573,22 +573,22 @@ protected theorem bit0Inj : ∀ {n m : Nat}, bit0 n = bit0 m → n = m
|
|||
have succ (n + n) = succ (m + m), from this,
|
||||
have n + n = m + m, from Nat.noConfusion this id,
|
||||
have n = m, from bit0Inj this,
|
||||
congrArg (λ a, a + 1) this
|
||||
congrArg (fun a => a + 1) this
|
||||
|
||||
protected theorem bit1Inj : ∀ {n m : Nat}, bit1 n = bit1 m → n = m :=
|
||||
λ n m h,
|
||||
fun n m h =>
|
||||
have succ (bit0 n) = succ (bit0 m), from Nat.bit1EqSuccBit0 n ▸ Nat.bit1EqSuccBit0 m ▸ h,
|
||||
have bit0 n = bit0 m, from Nat.noConfusion this id,
|
||||
Nat.bit0Inj this
|
||||
|
||||
protected theorem bit0Ne {n m : Nat} : n ≠ m → bit0 n ≠ bit0 m :=
|
||||
λ h₁ h₂, absurd (Nat.bit0Inj h₂) h₁
|
||||
fun h₁ h₂ => absurd (Nat.bit0Inj h₂) h₁
|
||||
|
||||
protected theorem bit1Ne {n m : Nat} : n ≠ m → bit1 n ≠ bit1 m :=
|
||||
λ h₁ h₂, absurd (Nat.bit1Inj h₂) h₁
|
||||
fun h₁ h₂ => absurd (Nat.bit1Inj h₂) h₁
|
||||
|
||||
protected theorem zeroNeBit0 {n : Nat} : n ≠ 0 → 0 ≠ bit0 n :=
|
||||
λ h, Ne.symm (Nat.bit0NeZero h)
|
||||
fun h => Ne.symm (Nat.bit0NeZero h)
|
||||
|
||||
protected theorem zeroNeBit1 (n : Nat) : 0 ≠ bit1 n :=
|
||||
Ne.symm (Nat.bit1NeZero n)
|
||||
|
|
@ -597,7 +597,7 @@ protected theorem oneNeBit0 (n : Nat) : 1 ≠ bit0 n :=
|
|||
Ne.symm (Nat.bit0NeOne n)
|
||||
|
||||
protected theorem oneNeBit1 {n : Nat} : n ≠ 0 → 1 ≠ bit1 n :=
|
||||
λ h, Ne.symm (Nat.bit1NeOne h)
|
||||
fun h => Ne.symm (Nat.bit1NeOne h)
|
||||
|
||||
protected theorem oneLtBit1 : ∀ {n : Nat}, n ≠ 0 → 1 < bit1 n
|
||||
| 0 h := absurd rfl h
|
||||
|
|
@ -682,10 +682,10 @@ theorem powLePowOfLeRight {n : Nat} (hx : n > 0) {i : Nat} : ∀ {j}, i ≤ j
|
|||
this.symm ▸ Nat.leRefl _
|
||||
| (succ j) h :=
|
||||
Or.elim (ltOrEqOrLeSucc h)
|
||||
(λ h, show n^i ≤ n^j * n, from
|
||||
(fun h => show n^i ≤ n^j * n, from
|
||||
suffices n^i * 1 ≤ n^j * n, from Nat.mulOne (n^i) ▸ this,
|
||||
Nat.mulLeMul (powLePowOfLeRight h) hx)
|
||||
(λ h, h.symm ▸ Nat.leRefl _)
|
||||
(fun h => h.symm ▸ Nat.leRefl _)
|
||||
|
||||
theorem posPowOfPos {n : Nat} (m : Nat) (h : 0 < n) : 0 < n^m :=
|
||||
powLePowOfLeRight h (Nat.zeroLe _)
|
||||
|
|
@ -706,6 +706,6 @@ Nat.foldAux f i.2 (i.2 - i.1) a
|
|||
Nat.anyAux f i.2 (i.2 - i.1)
|
||||
|
||||
@[inline] def allI (f : Nat → Bool) (i : Nat × Nat) : Bool :=
|
||||
!Nat.anyAux (λ a, !f a) i.2 (i.2 - i.1)
|
||||
!Nat.anyAux (fun a => !f a) i.2 (i.2 - i.1)
|
||||
|
||||
end Prod
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import init.wf init.data.nat.basic
|
|||
namespace Nat
|
||||
|
||||
private def divRecLemma {x y : Nat} : 0 < y ∧ y ≤ x → x - y < x :=
|
||||
λ h, And.rec (λ ypos ylex, subLt (Nat.ltOfLtOfLe ypos ylex) ypos) h
|
||||
fun h => And.rec (fun ypos ylex => subLt (Nat.ltOfLtOfLe ypos ylex) ypos) h
|
||||
|
||||
private def div.F (x : Nat) (f : Π x₁, x₁ < x → Nat → Nat) (y : Nat) : Nat :=
|
||||
if h : 0 < y ∧ y ≤ x then f (x - y) (divRecLemma h) y + 1 else zero
|
||||
|
|
@ -69,39 +69,39 @@ div.inductionOn x y h₁ h₂
|
|||
|
||||
theorem modZero (a : Nat) : a % 0 = a :=
|
||||
suffices (if 0 < 0 ∧ 0 ≤ a then (a - 0) % 0 else a) = a, from (modDef a 0).symm ▸ this,
|
||||
have h : ¬ (0 < 0 ∧ 0 ≤ a), from λ ⟨h₁, _⟩, absurd h₁ (Nat.ltIrrefl _),
|
||||
have h : ¬ (0 < 0 ∧ 0 ≤ a), from fun ⟨h₁, _⟩ => absurd h₁ (Nat.ltIrrefl _),
|
||||
ifNeg h
|
||||
|
||||
theorem modEqOfLt {a b : Nat} (h : a < b) : a % b = a :=
|
||||
suffices (if 0 < b ∧ b ≤ a then (a - b) % b else a) = a, from (modDef a b).symm ▸ this,
|
||||
have h' : ¬(0 < b ∧ b ≤ a), from λ ⟨_, h₁⟩, absurd h₁ (Nat.notLeOfGt h),
|
||||
have h' : ¬(0 < b ∧ b ≤ a), from fun ⟨_, h₁⟩ => absurd h₁ (Nat.notLeOfGt h),
|
||||
ifNeg h'
|
||||
|
||||
theorem modEqSubMod {a b : Nat} (h : a ≥ b) : a % b = (a - b) % b :=
|
||||
Or.elim (eqZeroOrPos b)
|
||||
(λ h₁, h₁.symm ▸ (Nat.subZero a).symm ▸ rfl)
|
||||
(λ h₁, (modDef a b).symm ▸ ifPos ⟨h₁, h⟩)
|
||||
(fun h₁ => h₁.symm ▸ (Nat.subZero a).symm ▸ rfl)
|
||||
(fun h₁ => (modDef a b).symm ▸ ifPos ⟨h₁, h⟩)
|
||||
|
||||
theorem modLt (x : Nat) {y : Nat} : y > 0 → x % y < y :=
|
||||
mod.inductionOn x y
|
||||
(λ x y ⟨_, h₁⟩ h₂ h₃,
|
||||
(fun (x y) ⟨_, h₁⟩ (h₂ h₃) =>
|
||||
have ih : (x - y) % y < y, from h₂ h₃,
|
||||
have Heq : x % y = (x - y) % y, from modEqSubMod h₁,
|
||||
Heq.symm ▸ ih)
|
||||
(λ x y h₁ h₂,
|
||||
(fun x y h₁ h₂ =>
|
||||
have h₁ : ¬ 0 < y ∨ ¬ y ≤ x, from Iff.mp (Decidable.notAndIffOrNot _ _) h₁,
|
||||
Or.elim h₁
|
||||
(λ h₁, absurd h₂ h₁)
|
||||
(λ h₁,
|
||||
(fun h₁ => absurd h₂ h₁)
|
||||
(fun h₁ =>
|
||||
have hgt : y > x, from gtOfNotLe h₁,
|
||||
have Heq : x % y = x, from modEqOfLt hgt,
|
||||
Heq.symm ▸ hgt))
|
||||
|
||||
theorem modLe (x y : Nat) : x % y ≤ x :=
|
||||
Or.elim (Nat.ltOrGe x y)
|
||||
(λ h₁ : x < y, (modEqOfLt h₁).symm ▸ Nat.leRefl _)
|
||||
(λ h₁ : x ≥ y, Or.elim (eqZeroOrPos y)
|
||||
(λ h₂ : y = 0, h₂.symm ▸ (Nat.modZero x).symm ▸ Nat.leRefl _)
|
||||
(λ h₂ : y > 0, Nat.leTrans (Nat.leOfLt (Nat.modLt _ h₂)) h₁))
|
||||
(fun (h₁ : x < y) => (modEqOfLt h₁).symm ▸ Nat.leRefl _)
|
||||
(fun (h₁ : x ≥ y) => Or.elim (eqZeroOrPos y)
|
||||
(fun (h₂ : y = 0) => h₂.symm ▸ (Nat.modZero x).symm ▸ Nat.leRefl _)
|
||||
(fun (h₂ : y > 0) => Nat.leTrans (Nat.leOfLt (Nat.modLt _ h₂)) h₁))
|
||||
|
||||
end Nat
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ def toMonad {m : Type → Type} [Monad m] [Alternative m] {A} : Option A → m A
|
|||
Option.bind o (some ∘ f)
|
||||
|
||||
theorem mapId {α} : (Option.map id : Option α → Option α) = id :=
|
||||
funext (λo, match o with | none := rfl | some x := rfl)
|
||||
funext (fun o => match o with | none := rfl | some x := rfl)
|
||||
|
||||
instance : Monad Option :=
|
||||
{pure := @some, bind := @Option.bind, map := @Option.map}
|
||||
|
|
@ -76,13 +76,13 @@ instance (α : Type u) : Inhabited (Option α) :=
|
|||
⟨none⟩
|
||||
|
||||
instance {α : Type u} [DecidableEq α] : DecidableEq (Option α) :=
|
||||
{decEq := λ a b, match a, b with
|
||||
{decEq := fun a b => match a, b with
|
||||
| none, none := isTrue rfl
|
||||
| none, (some v₂) := isFalse (λ h, Option.noConfusion h)
|
||||
| (some v₁), none := isFalse (λ h, Option.noConfusion h)
|
||||
| none, (some v₂) := isFalse (fun h => Option.noConfusion h)
|
||||
| (some v₁), none := isFalse (fun h => Option.noConfusion h)
|
||||
| (some v₁), (some v₂) :=
|
||||
match decEq v₁ v₂ with
|
||||
| (isTrue e) := isTrue (congrArg (@some α) e)
|
||||
| (isFalse n) := isFalse (λ h, Option.noConfusion h (λ e, absurd e n))}
|
||||
| (isFalse n) := isFalse (fun h => Option.noConfusion h (fun e => absurd e n))}
|
||||
|
||||
instance {α : Type u} [HasLess α] : HasLess (Option α) := ⟨Option.lt HasLess.Less⟩
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ inductive Ordering
|
|||
| lt | Eq | gt
|
||||
|
||||
instance : HasRepr Ordering :=
|
||||
⟨(λ s, match s with | Ordering.lt := "lt" | Ordering.Eq := "Eq" | Ordering.gt := "gt")⟩
|
||||
⟨(fun s => match s with | Ordering.lt := "lt" | Ordering.Eq := "Eq" | Ordering.gt := "gt")⟩
|
||||
|
||||
namespace Ordering
|
||||
def swap : Ordering → Ordering
|
||||
|
|
@ -40,20 +40,20 @@ def cmp {α : Type u} [HasLess α] [DecidableRel (HasLess.Less : α → α → P
|
|||
cmpUsing HasLess.Less a b
|
||||
|
||||
instance : DecidableEq Ordering :=
|
||||
{decEq := λ a b,
|
||||
{decEq := fun a b =>
|
||||
match a with
|
||||
| Ordering.lt :=
|
||||
match b with
|
||||
| Ordering.lt := isTrue rfl
|
||||
| Ordering.Eq := isFalse (λ h, Ordering.noConfusion h)
|
||||
| Ordering.gt := isFalse (λ h, Ordering.noConfusion h)
|
||||
| Ordering.Eq := isFalse (fun h => Ordering.noConfusion h)
|
||||
| Ordering.gt := isFalse (fun h => Ordering.noConfusion h)
|
||||
| Ordering.Eq :=
|
||||
match b with
|
||||
| Ordering.lt := isFalse (λ h, Ordering.noConfusion h)
|
||||
| Ordering.lt := isFalse (fun h => Ordering.noConfusion h)
|
||||
| Ordering.Eq := isTrue rfl
|
||||
| Ordering.gt := isFalse (λ h, Ordering.noConfusion h)
|
||||
| Ordering.gt := isFalse (fun h => Ordering.noConfusion h)
|
||||
| Ordering.gt :=
|
||||
match b with
|
||||
| Ordering.lt := isFalse (λ h, Ordering.noConfusion h)
|
||||
| Ordering.Eq := isFalse (λ h, Ordering.noConfusion h)
|
||||
| Ordering.lt := isFalse (fun h => Ordering.noConfusion h)
|
||||
| Ordering.Eq := isFalse (fun h => Ordering.noConfusion h)
|
||||
| Ordering.gt := isTrue rfl}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ partial def setAux : PersistentArrayNode α → USize → USize → α → Persi
|
|||
let j := div2Shift i shift;
|
||||
let i := mod2Shift i shift;
|
||||
let shift := shift - initShift;
|
||||
node $ cs.modify j.toNat $ λ c, setAux c i shift a
|
||||
node $ cs.modify j.toNat $ fun c => setAux c i shift a
|
||||
| (leaf cs) i _ a := leaf (cs.set i.toNat a)
|
||||
|
||||
def set (t : PersistentArray α) (i : Nat) (a : α) : PersistentArray α :=
|
||||
|
|
@ -73,7 +73,7 @@ else
|
|||
let j := div2Shift i shift;
|
||||
let i := mod2Shift i shift;
|
||||
let shift := shift - initShift;
|
||||
node $ cs.modify j.toNat $ λ c, modifyAux c i shift
|
||||
node $ cs.modify j.toNat $ fun c => modifyAux c i shift
|
||||
| (leaf cs) i _ := leaf (cs.modify i.toNat f)
|
||||
|
||||
@[specialize] def modify [Inhabited α] (t : PersistentArray α) (i : Nat) (f : α → α) : PersistentArray α :=
|
||||
|
|
@ -98,7 +98,7 @@ partial def insertNewLeaf : PersistentArrayNode α → USize → USize → Array
|
|||
let i := mod2Shift i shift;
|
||||
let shift := shift - initShift;
|
||||
if j.toNat < cs.size then
|
||||
node $ cs.modify j.toNat $ λ c, insertNewLeaf c i shift a
|
||||
node $ cs.modify j.toNat $ fun c => insertNewLeaf c i shift a
|
||||
else
|
||||
node $ cs.push $ mkNewPath shift a
|
||||
| n _ _ _ := n -- unreachable
|
||||
|
|
@ -129,7 +129,7 @@ section
|
|||
variables {m : Type v → Type v} [Monad m]
|
||||
|
||||
@[specialize] partial def mfoldlAux (f : β → α → m β) : PersistentArrayNode α → β → m β
|
||||
| (node cs) b := cs.mfoldl (λ b c, mfoldlAux c b) b
|
||||
| (node cs) b := cs.mfoldl (fun b c => mfoldlAux c b) b
|
||||
| (leaf vs) b := vs.mfoldl f b
|
||||
|
||||
@[specialize] def mfoldl (f : β → α → m β) (b : β) (t : PersistentArray α) : m β :=
|
||||
|
|
@ -141,13 +141,13 @@ end
|
|||
Id.run (t.mfoldl f b)
|
||||
|
||||
def toList (t : PersistentArray α) : List α :=
|
||||
(t.foldl (λ xs x, x :: xs) []).reverse
|
||||
(t.foldl (fun xs x => x :: xs) []).reverse
|
||||
|
||||
section
|
||||
variables {m : Type v → Type v} [Monad m]
|
||||
|
||||
@[specialize] partial def mmapAux (f : α → m β) : PersistentArrayNode α → m (PersistentArrayNode β)
|
||||
| (node cs) := node <$> cs.mmap (λ c, mmapAux c)
|
||||
| (node cs) := node <$> cs.mmap (fun c => mmapAux c)
|
||||
| (leaf vs) := leaf <$> vs.mmap f
|
||||
|
||||
@[specialize] def mmap (f : α → m β) (t : PersistentArray α) : m (PersistentArray β) :=
|
||||
|
|
@ -166,7 +166,7 @@ structure Stats :=
|
|||
|
||||
partial def collectStats : PersistentArrayNode α → Stats → Nat → Stats
|
||||
| (node cs) s d :=
|
||||
cs.foldl (λ s c, collectStats c s (d+1))
|
||||
cs.foldl (fun s c => collectStats c s (d+1))
|
||||
{ numNodes := s.numNodes + 1,
|
||||
depth := Nat.max d s.depth, .. s }
|
||||
| (leaf vs) s d := { numNodes := s.numNodes + 1, depth := Nat.max d s.depth, .. s }
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ structure StdGen :=
|
|||
def stdRange := (1, 2147483562)
|
||||
|
||||
instance : HasRepr StdGen :=
|
||||
{ repr := λ ⟨s1, s2⟩, "⟨" ++ toString s1 ++ ", " ++ toString s2 ++ "⟩" }
|
||||
{ repr := fun ⟨s1, s2⟩ => "⟨" ++ toString s1 ++ ", " ++ toString s2 ++ "⟩" }
|
||||
|
||||
def stdNext : StdGen → Nat × StdGen
|
||||
| ⟨s1, s2⟩ :=
|
||||
|
|
@ -58,7 +58,7 @@ def stdSplit : StdGen → StdGen × StdGen
|
|||
(leftG, rightG)
|
||||
|
||||
instance : RandomGen StdGen :=
|
||||
{range := λ _, stdRange,
|
||||
{range := fun _ => stdRange,
|
||||
next := stdNext,
|
||||
split := stdSplit}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ def depth (f : Nat → Nat → Nat) : RBNode α β → Nat
|
|||
| leaf := 0
|
||||
| (node _ l _ _ r) := succ (f (depth l) (depth r))
|
||||
|
||||
protected def min : RBNode α β → Option (Sigma (λ k : α, β k))
|
||||
protected def min : RBNode α β → Option (Sigma (fun k => β k))
|
||||
| leaf := none
|
||||
| (node _ leaf k v _) := some ⟨k, v⟩
|
||||
| (node _ l k v _) := min l
|
||||
|
||||
protected def max : RBNode α β → Option (Sigma (λ k : α, β k))
|
||||
protected def max : RBNode α β → Option (Sigma (fun k => β k))
|
||||
| leaf := none
|
||||
| (node _ _ k v leaf) := some ⟨k, v⟩
|
||||
| (node _ _ k v r) := max r
|
||||
|
|
@ -174,14 +174,14 @@ end Erase
|
|||
section Membership
|
||||
variable (lt : α → α → Bool)
|
||||
|
||||
@[specialize] def findCore : RBNode α β → Π k : α, Option (Sigma (λ k : α, β k))
|
||||
@[specialize] def findCore : RBNode α β → Π k : α, Option (Sigma (fun k => β k))
|
||||
| leaf x := none
|
||||
| (node _ a ky vy b) x :=
|
||||
if lt x ky then findCore a x
|
||||
else if lt ky x then findCore b x
|
||||
else some ⟨ky, vy⟩
|
||||
|
||||
@[specialize] def find {β : Type v} : RBNode α (λ _, β) → α → Option β
|
||||
@[specialize] def find {β : Type v} : RBNode α (fun _ => β) → α → Option β
|
||||
| leaf x := none
|
||||
| (node _ a ky vy b) x :=
|
||||
if lt x ky then find a x
|
||||
|
|
@ -209,7 +209,7 @@ open RBNode
|
|||
/- TODO(Leo): define dRBMap -/
|
||||
|
||||
def RBMap (α : Type u) (β : Type v) (lt : α → α → Bool) : Type (max u v) :=
|
||||
{t : RBNode α (λ _, β) // t.WellFormed lt }
|
||||
{t : RBNode α (fun _ => β) // t.WellFormed lt }
|
||||
|
||||
@[inline] def mkRBMap (α : Type u) (β : Type v) (lt : α → α → Bool) : RBMap α β lt :=
|
||||
⟨leaf, WellFormed.leafWff lt⟩
|
||||
|
|
@ -236,14 +236,14 @@ t.val.depth f
|
|||
| b ⟨t, _⟩ := t.mfold f b
|
||||
|
||||
@[inline] def mfor {m : Type w → Type w'} [Monad m] (f : α → β → m σ) (t : RBMap α β lt) : m PUnit :=
|
||||
t.mfold (λ _ k v, f k v *> pure ⟨⟩) ⟨⟩
|
||||
t.mfold (fun _ k v => f k v *> pure ⟨⟩) ⟨⟩
|
||||
|
||||
@[inline] def isEmpty : RBMap α β lt → Bool
|
||||
| ⟨leaf, _⟩ := true
|
||||
| _ := false
|
||||
|
||||
@[specialize] def toList : RBMap α β lt → List (α × β)
|
||||
| ⟨t, _⟩ := t.revFold (λ ps k v, (k, v)::ps) []
|
||||
| ⟨t, _⟩ := t.revFold (fun ps k v => (k, v)::ps) []
|
||||
|
||||
@[inline] protected def min : RBMap α β lt → Option (α × β)
|
||||
| ⟨t, _⟩ :=
|
||||
|
|
@ -258,7 +258,7 @@ t.mfold (λ _ k v, f k v *> pure ⟨⟩) ⟨⟩
|
|||
| none := none
|
||||
|
||||
instance [HasRepr α] [HasRepr β] : HasRepr (RBMap α β lt) :=
|
||||
⟨λ t, "rbmapOf " ++ repr t.toList⟩
|
||||
⟨fun t => "rbmapOf " ++ repr t.toList⟩
|
||||
|
||||
@[inline] def insert : RBMap α β lt → α → β → RBMap α β lt
|
||||
| ⟨t, w⟩ k v := ⟨t.insert lt k v, WellFormed.insertWff w rfl⟩
|
||||
|
|
@ -270,7 +270,7 @@ instance [HasRepr α] [HasRepr β] : HasRepr (RBMap α β lt) :=
|
|||
| [] := mkRBMap _ _ _
|
||||
| (⟨k,v⟩::xs) := (ofList xs).insert k v
|
||||
|
||||
@[inline] def findCore : RBMap α β lt → α → Option (Sigma (λ k : α, β))
|
||||
@[inline] def findCore : RBMap α β lt → α → Option (Sigma (fun (k : α) => β))
|
||||
| ⟨t, _⟩ x := t.findCore lt x
|
||||
|
||||
@[inline] def find : RBMap α β lt → α → Option β
|
||||
|
|
@ -278,14 +278,14 @@ instance [HasRepr α] [HasRepr β] : HasRepr (RBMap α β lt) :=
|
|||
|
||||
/-- (lowerBound k) retrieves the kv pair of the largest key smaller than or equal to `k`,
|
||||
if it exists. -/
|
||||
@[inline] def lowerBound : RBMap α β lt → α → Option (Sigma (λ k : α, β))
|
||||
@[inline] def lowerBound : RBMap α β lt → α → Option (Sigma (fun (k : α) => β))
|
||||
| ⟨t, _⟩ x := t.lowerBound lt x none
|
||||
|
||||
@[inline] def contains (t : RBMap α β lt) (a : α) : Bool :=
|
||||
(t.find a).isSome
|
||||
|
||||
@[inline] def fromList (l : List (α × β)) (lt : α → α → Bool) : RBMap α β lt :=
|
||||
l.foldl (λ r p, r.insert p.1 p.2) (mkRBMap α β lt)
|
||||
l.foldl (fun r p => r.insert p.1 p.2) (mkRBMap α β lt)
|
||||
|
||||
@[inline] def all : RBMap α β lt → (α → β → Bool) → Bool
|
||||
| ⟨t, _⟩ p := t.all p
|
||||
|
|
@ -294,7 +294,7 @@ l.foldl (λ r p, r.insert p.1 p.2) (mkRBMap α β lt)
|
|||
| ⟨t, _⟩ p := t.any p
|
||||
|
||||
def size (m : RBMap α β lt) : Nat :=
|
||||
m.fold (λ sz _ _, sz+1) 0
|
||||
m.fold (fun sz _ _ => sz+1) 0
|
||||
|
||||
def maxDepth (t : RBMap α β lt) : Nat :=
|
||||
t.val.depth Nat.max
|
||||
|
|
|
|||
|
|
@ -23,22 +23,22 @@ variables {α : Type u} {β : Type v} {lt : α → α → Bool}
|
|||
RBMap.depth f t
|
||||
|
||||
@[inline] def fold (f : β → α → β) (b : β) (t : RBTree α lt) : β :=
|
||||
RBMap.fold (λ r a _, f r a) b t
|
||||
RBMap.fold (fun r a _ => f r a) b t
|
||||
|
||||
@[inline] def revFold (f : β → α → β) (b : β) (t : RBTree α lt) : β :=
|
||||
RBMap.revFold (λ r a _, f r a) b t
|
||||
RBMap.revFold (fun r a _ => f r a) b t
|
||||
|
||||
@[inline] def mfold {m : Type v → Type w} [Monad m] (f : β → α → m β) (b : β) (t : RBTree α lt) : m β :=
|
||||
RBMap.mfold (λ r a _, f r a) b t
|
||||
RBMap.mfold (fun r a _ => f r a) b t
|
||||
|
||||
@[inline] def mfor {m : Type v → Type w} [Monad m] (f : α → m β) (t : RBTree α lt) : m PUnit :=
|
||||
t.mfold (λ _ a, f a *> pure ⟨⟩) ⟨⟩
|
||||
t.mfold (fun _ a => f a *> pure ⟨⟩) ⟨⟩
|
||||
|
||||
@[inline] def isEmpty (t : RBTree α lt) : Bool :=
|
||||
RBMap.isEmpty t
|
||||
|
||||
@[specialize] def toList (t : RBTree α lt) : List α :=
|
||||
t.revFold (λ as a, a::as) []
|
||||
t.revFold (fun as a => a::as) []
|
||||
|
||||
@[inline] protected def min (t : RBTree α lt) : Option α :=
|
||||
match RBMap.min t with
|
||||
|
|
@ -51,12 +51,12 @@ match RBMap.max t with
|
|||
| none := none
|
||||
|
||||
instance [HasRepr α] : HasRepr (RBTree α lt) :=
|
||||
⟨λ t, "rbtreeOf " ++ repr t.toList⟩
|
||||
⟨fun t => "rbtreeOf " ++ repr t.toList⟩
|
||||
|
||||
@[inline] def insert (t : RBTree α lt) (a : α) : RBTree α lt :=
|
||||
RBMap.insert t a ()
|
||||
|
||||
instance : HasInsert α (RBTree α lt) := ⟨λ a s, s.insert a⟩
|
||||
instance : HasInsert α (RBTree α lt) := ⟨fun a s => s.insert a⟩
|
||||
|
||||
@[inline] def erase (t : RBTree α lt) (a : α) : RBTree α lt :=
|
||||
RBMap.erase t a
|
||||
|
|
@ -77,13 +77,13 @@ def fromList (l : List α) (lt : α → α → Bool) : RBTree α lt :=
|
|||
l.foldl insert (mkRBTree α lt)
|
||||
|
||||
@[inline] def all (t : RBTree α lt) (p : α → Bool) : Bool :=
|
||||
RBMap.all t (λ a _, p a)
|
||||
RBMap.all t (fun a _ => p a)
|
||||
|
||||
@[inline] def any (t : RBTree α lt) (p : α → Bool) : Bool :=
|
||||
RBMap.any t (λ a _, p a)
|
||||
RBMap.any t (fun a _ => p a)
|
||||
|
||||
def subset (t₁ t₂ : RBTree α lt) : Bool :=
|
||||
t₁.all $ λ a, (t₂.find a).toBool
|
||||
t₁.all $ fun a => (t₂.find a).toBool
|
||||
|
||||
def seteq (t₁ t₂ : RBTree α lt) : Bool :=
|
||||
subset t₁ t₂ && subset t₂ t₁
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ instance {α : Type u} [HasRepr α] : HasRepr (id α) :=
|
|||
inferInstanceAs (HasRepr α)
|
||||
|
||||
instance : HasRepr Bool :=
|
||||
⟨λ b, cond b "true" "false"⟩
|
||||
⟨fun b => cond b "true" "false"⟩
|
||||
|
||||
instance {p : Prop} : HasRepr (Decidable p) :=
|
||||
⟨λ b : Decidable p, @ite p b _ "true" "false"⟩
|
||||
⟨fun b => @ite p b _ "true" "false"⟩
|
||||
|
||||
protected def List.reprAux {α : Type u} [HasRepr α] : Bool → List α → String
|
||||
| b [] := ""
|
||||
|
|
@ -37,22 +37,22 @@ instance {α : Type u} [HasRepr α] : HasRepr (List α) :=
|
|||
⟨List.repr⟩
|
||||
|
||||
instance : HasRepr Unit :=
|
||||
⟨λ u, "()"⟩
|
||||
⟨fun u => "()"⟩
|
||||
|
||||
instance {α : Type u} [HasRepr α] : HasRepr (Option α) :=
|
||||
⟨λ o, match o with | none := "none" | (some a) := "(some " ++ repr a ++ ")"⟩
|
||||
⟨fun o => match o with | none := "none" | (some a) := "(some " ++ repr a ++ ")"⟩
|
||||
|
||||
instance {α : Type u} {β : Type v} [HasRepr α] [HasRepr β] : HasRepr (α ⊕ β) :=
|
||||
⟨λ s, match s with | (inl a) := "(inl " ++ repr a ++ ")" | (inr b) := "(inr " ++ repr b ++ ")"⟩
|
||||
⟨fun s => match s with | (inl a) := "(inl " ++ repr a ++ ")" | (inr b) := "(inr " ++ repr b ++ ")"⟩
|
||||
|
||||
instance {α : Type u} {β : Type v} [HasRepr α] [HasRepr β] : HasRepr (α × β) :=
|
||||
⟨λ ⟨a, b⟩, "(" ++ repr a ++ ", " ++ repr b ++ ")"⟩
|
||||
⟨fun ⟨a, b⟩ => "(" ++ repr a ++ ", " ++ repr b ++ ")"⟩
|
||||
|
||||
instance {α : Type u} {β : α → Type v} [HasRepr α] [s : ∀ x, HasRepr (β x)] : HasRepr (Sigma β) :=
|
||||
⟨λ ⟨a, b⟩, "⟨" ++ repr a ++ ", " ++ repr b ++ "⟩"⟩
|
||||
⟨fun ⟨a, b⟩ => "⟨" ++ repr a ++ ", " ++ repr b ++ "⟩"⟩
|
||||
|
||||
instance {α : Type u} {p : α → Prop} [HasRepr α] : HasRepr (Subtype p) :=
|
||||
⟨λ s, repr (val s)⟩
|
||||
⟨fun s => repr (val s)⟩
|
||||
|
||||
namespace Nat
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ else if c.toNat <= 31 ∨ c = '\x7f' then "\\x" ++ charToHex c
|
|||
else String.singleton c
|
||||
|
||||
instance : HasRepr Char :=
|
||||
⟨λ c, "'" ++ Char.quoteCore c ++ "'"⟩
|
||||
⟨fun c => "'" ++ Char.quoteCore c ++ "'"⟩
|
||||
|
||||
def String.quoteAux : List Char → String
|
||||
| [] := ""
|
||||
|
|
@ -126,18 +126,18 @@ instance : HasRepr String :=
|
|||
⟨String.quote⟩
|
||||
|
||||
instance : HasRepr Substring :=
|
||||
⟨λ s, String.quote s.toString ++ ".toSubstring"⟩
|
||||
⟨fun s => String.quote s.toString ++ ".toSubstring"⟩
|
||||
|
||||
instance : HasRepr String.Iterator :=
|
||||
⟨λ it, it.remainingToString.quote ++ ".mkIterator"⟩
|
||||
⟨fun it => it.remainingToString.quote ++ ".mkIterator"⟩
|
||||
|
||||
instance (n : Nat) : HasRepr (Fin n) :=
|
||||
⟨λ f, repr (Fin.val f)⟩
|
||||
⟨fun f => repr (Fin.val f)⟩
|
||||
|
||||
instance : HasRepr UInt16 := ⟨λ n, repr n.toNat⟩
|
||||
instance : HasRepr UInt32 := ⟨λ n, repr n.toNat⟩
|
||||
instance : HasRepr UInt64 := ⟨λ n, repr n.toNat⟩
|
||||
instance : HasRepr USize := ⟨λ n, repr n.toNat⟩
|
||||
instance : HasRepr UInt16 := ⟨fun n => repr n.toNat⟩
|
||||
instance : HasRepr UInt32 := ⟨fun n => repr n.toNat⟩
|
||||
instance : HasRepr UInt64 := ⟨fun n => repr n.toNat⟩
|
||||
instance : HasRepr USize := ⟨fun n => repr n.toNat⟩
|
||||
|
||||
def Char.repr (c : Char) : String :=
|
||||
repr c
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ def String.decEq (s₁ s₂ : @& String) : Decidable (s₁ = s₂) :=
|
|||
match s₁, s₂ with
|
||||
| ⟨s₁⟩, ⟨s₂⟩ :=
|
||||
if h : s₁ = s₂ then isTrue (congrArg _ h)
|
||||
else isFalse (λ h', String.noConfusion h' (λ h', absurd h' h))
|
||||
else isFalse (fun h' => String.noConfusion h' (fun h' => absurd h' h))
|
||||
|
||||
instance : DecidableEq String :=
|
||||
{decEq := String.decEq}
|
||||
|
|
@ -33,7 +33,7 @@ def List.asString (s : List Char) : String :=
|
|||
|
||||
namespace String
|
||||
instance : HasLess String :=
|
||||
⟨λ s₁ s₂, s₁.data < s₂.data⟩
|
||||
⟨fun s₁ s₂ => s₁.data < s₂.data⟩
|
||||
|
||||
@[extern cpp "lean::string_dec_lt"]
|
||||
instance decLt (s₁ s₂ : @& String) : Decidable (s₁ < s₂) :=
|
||||
|
|
@ -170,13 +170,13 @@ instance : HasAppend String :=
|
|||
def str : String → Char → String := push
|
||||
|
||||
def pushn (s : String) (c : Char) (n : Nat) : String :=
|
||||
n.repeat (λ s, s.push c) s
|
||||
n.repeat (fun s => s.push c) s
|
||||
|
||||
def isEmpty (s : String) : Bool :=
|
||||
s.bsize == 0
|
||||
|
||||
def join (l : List String) : String :=
|
||||
l.foldl (λ r s, r ++ s) ""
|
||||
l.foldl (fun r s => r ++ s) ""
|
||||
|
||||
def singleton (c : Char) : String :=
|
||||
"".push c
|
||||
|
|
@ -292,10 +292,10 @@ foldrAux f a s s.bsize 0
|
|||
anyAux s s.bsize p 0
|
||||
|
||||
@[inline] def all (s : String) (p : Char → Bool) : Bool :=
|
||||
!s.any (λ c, !p c)
|
||||
!s.any (fun c => !p c)
|
||||
|
||||
def contains (s : String) (c : Char) : Bool :=
|
||||
s.any (λ a, a == c)
|
||||
s.any (fun a => a == c)
|
||||
|
||||
@[specialize] partial def mapAux (f : Char → Char) : Pos → String → String
|
||||
| i s :=
|
||||
|
|
@ -309,10 +309,10 @@ s.any (λ a, a == c)
|
|||
mapAux f 0 s
|
||||
|
||||
def toNat (s : String) : Nat :=
|
||||
s.foldl (λ n c, n*10 + (c.toNat - '0'.toNat)) 0
|
||||
s.foldl (fun n c => n*10 + (c.toNat - '0'.toNat)) 0
|
||||
|
||||
def isNat (s : String) : Bool :=
|
||||
s.all $ λ c, c.isDigit
|
||||
s.all $ fun c => c.isDigit
|
||||
|
||||
partial def isPrefixOfAux (p s : String) : Pos → Bool
|
||||
| i :=
|
||||
|
|
@ -409,10 +409,10 @@ match s with
|
|||
| ⟨s, b, e⟩ := String.anyAux s e p b
|
||||
|
||||
@[inline] def all (s : Substring) (p : Char → Bool) : Bool :=
|
||||
!s.any (λ c, !p c)
|
||||
!s.any (fun c => !p c)
|
||||
|
||||
def contains (s : Substring) (c : Char) : Bool :=
|
||||
s.any (λ a, a == c)
|
||||
s.any (fun a => a == c)
|
||||
|
||||
@[specialize] partial def takeWhileAux (s : String) (stopPos : String.Pos) (p : Char → Bool) : String.Pos → String.Pos
|
||||
| i :=
|
||||
|
|
@ -462,10 +462,10 @@ s.dropRightWhile Char.isWhitespace
|
|||
⟨s, b, e⟩
|
||||
|
||||
def toNat (s : Substring) : Nat :=
|
||||
s.foldl (λ n c, n*10 + (c.toNat - '0'.toNat)) 0
|
||||
s.foldl (fun n c => n*10 + (c.toNat - '0'.toNat)) 0
|
||||
|
||||
def isNat (s : Substring) : Bool :=
|
||||
s.all $ λ c, c.isDigit
|
||||
s.all $ fun c => c.isDigit
|
||||
|
||||
end Substring
|
||||
|
||||
|
|
|
|||
|
|
@ -19,20 +19,20 @@ instance {α : Type u} [HasToString α] : HasToString (id α) :=
|
|||
inferInstanceAs (HasToString α)
|
||||
|
||||
instance : HasToString String :=
|
||||
⟨λ s, s⟩
|
||||
⟨fun s => s⟩
|
||||
|
||||
instance : HasToString Substring :=
|
||||
⟨λ s, s.toString⟩
|
||||
⟨fun s => s.toString⟩
|
||||
|
||||
instance : HasToString String.Iterator :=
|
||||
⟨λ it, it.remainingToString⟩
|
||||
⟨fun it => it.remainingToString⟩
|
||||
|
||||
instance : HasToString Bool :=
|
||||
⟨λ b, cond b "true" "false"⟩
|
||||
⟨fun b => cond b "true" "false"⟩
|
||||
|
||||
instance {p : Prop} : HasToString (Decidable p) :=
|
||||
-- Remark: type class inference will not consider local instance `b` in the new Elaborator
|
||||
⟨λ b : Decidable p, @ite p b _ "true" "false"⟩
|
||||
⟨fun b => @ite p b _ "true" "false"⟩
|
||||
|
||||
protected def List.toStringAux {α : Type u} [HasToString α] : Bool → List α → String
|
||||
| b [] := ""
|
||||
|
|
@ -47,43 +47,43 @@ instance {α : Type u} [HasToString α] : HasToString (List α) :=
|
|||
⟨List.toString⟩
|
||||
|
||||
instance : HasToString Unit :=
|
||||
⟨λ u, "()"⟩
|
||||
⟨fun u => "()"⟩
|
||||
|
||||
instance : HasToString Nat :=
|
||||
⟨λ n, repr n⟩
|
||||
⟨fun n => repr n⟩
|
||||
|
||||
instance : HasToString Char :=
|
||||
⟨λ c, c.toString⟩
|
||||
⟨fun c => c.toString⟩
|
||||
|
||||
instance (n : Nat) : HasToString (Fin n) :=
|
||||
⟨λ f, toString (Fin.val f)⟩
|
||||
⟨fun f => toString (Fin.val f)⟩
|
||||
|
||||
instance : HasToString UInt8 :=
|
||||
⟨λ n, toString n.toNat⟩
|
||||
⟨fun n => toString n.toNat⟩
|
||||
|
||||
instance : HasToString UInt16 :=
|
||||
⟨λ n, toString n.toNat⟩
|
||||
⟨fun n => toString n.toNat⟩
|
||||
|
||||
instance : HasToString UInt32 :=
|
||||
⟨λ n, toString n.toNat⟩
|
||||
⟨fun n => toString n.toNat⟩
|
||||
|
||||
instance : HasToString UInt64 :=
|
||||
⟨λ n, toString n.toNat⟩
|
||||
⟨fun n => toString n.toNat⟩
|
||||
|
||||
instance : HasToString USize :=
|
||||
⟨λ n, toString n.toNat⟩
|
||||
⟨fun n => toString n.toNat⟩
|
||||
|
||||
instance {α : Type u} [HasToString α] : HasToString (Option α) :=
|
||||
⟨λ o, match o with | none := "none" | (some a) := "(some " ++ toString a ++ ")"⟩
|
||||
⟨fun o => match o with | none := "none" | (some a) := "(some " ++ toString a ++ ")"⟩
|
||||
|
||||
instance {α : Type u} {β : Type v} [HasToString α] [HasToString β] : HasToString (α ⊕ β) :=
|
||||
⟨λ s, match s with | (inl a) := "(inl " ++ toString a ++ ")" | (inr b) := "(inr " ++ toString b ++ ")"⟩
|
||||
⟨fun s => match s with | (inl a) := "(inl " ++ toString a ++ ")" | (inr b) := "(inr " ++ toString b ++ ")"⟩
|
||||
|
||||
instance {α : Type u} {β : Type v} [HasToString α] [HasToString β] : HasToString (α × β) :=
|
||||
⟨λ ⟨a, b⟩, "(" ++ toString a ++ ", " ++ toString b ++ ")"⟩
|
||||
⟨fun ⟨a, b⟩ => "(" ++ toString a ++ ", " ++ toString b ++ ")"⟩
|
||||
|
||||
instance {α : Type u} {β : α → Type v} [HasToString α] [s : ∀ x, HasToString (β x)] : HasToString (Sigma β) :=
|
||||
⟨λ ⟨a, b⟩, "⟨" ++ toString a ++ ", " ++ toString b ++ "⟩"⟩
|
||||
⟨fun ⟨a, b⟩ => "⟨" ++ toString a ++ ", " ++ toString b ++ "⟩"⟩
|
||||
|
||||
instance {α : Type u} {p : α → Prop} [HasToString α] : HasToString (Subtype p) :=
|
||||
⟨λ s, toString (val s)⟩
|
||||
⟨fun s => toString (val s)⟩
|
||||
|
|
|
|||
|
|
@ -49,17 +49,17 @@ instance : Inhabited UInt8 := ⟨0⟩
|
|||
|
||||
@[extern cpp inline "#1 == #2"]
|
||||
def UInt8.decEq (a b : UInt8) : Decidable (a = b) :=
|
||||
UInt8.casesOn a $ λ n, UInt8.casesOn b $ λ m,
|
||||
if h : n = m then isTrue (h ▸ rfl) else isFalse (λ h', UInt8.noConfusion h' (λ h', absurd h' h))
|
||||
UInt8.casesOn a $ fun n => UInt8.casesOn b $ fun m =>
|
||||
if h : n = m then isTrue (h ▸ rfl) else isFalse (fun h' => UInt8.noConfusion h' (fun h' => absurd h' h))
|
||||
|
||||
@[extern cpp inline "#1 < #2"]
|
||||
def UInt8.decLt (a b : UInt8) : Decidable (a < b) :=
|
||||
UInt8.casesOn a $ λ n, UInt8.casesOn b $ λ m,
|
||||
UInt8.casesOn a $ fun n => UInt8.casesOn b $ fun m =>
|
||||
inferInstanceAs (Decidable (n < m))
|
||||
|
||||
@[extern cpp inline "#1 <= #2"]
|
||||
def UInt8.decLe (a b : UInt8) : Decidable (a ≤ b) :=
|
||||
UInt8.casesOn a $ λ n, UInt8.casesOn b $ λ m,
|
||||
UInt8.casesOn a $ fun n => UInt8.casesOn b $ fun m =>
|
||||
inferInstanceAs (Decidable (n <= m))
|
||||
|
||||
instance : DecidableEq UInt8 := {decEq := UInt8.decEq}
|
||||
|
|
@ -107,17 +107,17 @@ instance : Inhabited UInt16 := ⟨0⟩
|
|||
|
||||
@[extern cpp inline "#1 == #2"]
|
||||
def UInt16.decEq (a b : UInt16) : Decidable (a = b) :=
|
||||
UInt16.casesOn a $ λ n, UInt16.casesOn b $ λ m,
|
||||
if h : n = m then isTrue (h ▸ rfl) else isFalse (λ h', UInt16.noConfusion h' (λ h', absurd h' h))
|
||||
UInt16.casesOn a $ fun n => UInt16.casesOn b $ fun m =>
|
||||
if h : n = m then isTrue (h ▸ rfl) else isFalse (fun h' => UInt16.noConfusion h' (fun h' => absurd h' h))
|
||||
|
||||
@[extern cpp inline "#1 < #2"]
|
||||
def UInt16.decLt (a b : UInt16) : Decidable (a < b) :=
|
||||
UInt16.casesOn a $ λ n, UInt16.casesOn b $ λ m,
|
||||
UInt16.casesOn a $ fun n => UInt16.casesOn b $ fun m =>
|
||||
inferInstanceAs (Decidable (n < m))
|
||||
|
||||
@[extern cpp inline "#1 <= #2"]
|
||||
def UInt16.decLe (a b : UInt16) : Decidable (a ≤ b) :=
|
||||
UInt16.casesOn a $ λ n, UInt16.casesOn b $ λ m,
|
||||
UInt16.casesOn a $ fun n => UInt16.casesOn b $ fun m =>
|
||||
inferInstanceAs (Decidable (n <= m))
|
||||
|
||||
instance : DecidableEq UInt16 := {decEq := UInt16.decEq}
|
||||
|
|
@ -165,17 +165,17 @@ instance : Inhabited UInt32 := ⟨0⟩
|
|||
|
||||
@[extern cpp inline "#1 == #2"]
|
||||
def UInt32.decEq (a b : UInt32) : Decidable (a = b) :=
|
||||
UInt32.casesOn a $ λ n, UInt32.casesOn b $ λ m,
|
||||
if h : n = m then isTrue (h ▸ rfl) else isFalse (λ h', UInt32.noConfusion h' (λ h', absurd h' h))
|
||||
UInt32.casesOn a $ fun n => UInt32.casesOn b $ fun m =>
|
||||
if h : n = m then isTrue (h ▸ rfl) else isFalse (fun h' => UInt32.noConfusion h' (fun h' => absurd h' h))
|
||||
|
||||
@[extern cpp inline "#1 < #2"]
|
||||
def UInt32.decLt (a b : UInt32) : Decidable (a < b) :=
|
||||
UInt32.casesOn a $ λ n, UInt32.casesOn b $ λ m,
|
||||
UInt32.casesOn a $ fun n => UInt32.casesOn b $ fun m =>
|
||||
inferInstanceAs (Decidable (n < m))
|
||||
|
||||
@[extern cpp inline "#1 <= #2"]
|
||||
def UInt32.decLe (a b : UInt32) : Decidable (a ≤ b) :=
|
||||
UInt32.casesOn a $ λ n, UInt32.casesOn b $ λ m,
|
||||
UInt32.casesOn a $ fun n => UInt32.casesOn b $ fun m =>
|
||||
inferInstanceAs (Decidable (n <= m))
|
||||
|
||||
instance : DecidableEq UInt32 := {decEq := UInt32.decEq}
|
||||
|
|
@ -223,17 +223,17 @@ instance : Inhabited UInt64 := ⟨0⟩
|
|||
|
||||
@[extern cpp inline "#1 == #2"]
|
||||
def UInt64.decEq (a b : UInt64) : Decidable (a = b) :=
|
||||
UInt64.casesOn a $ λ n, UInt64.casesOn b $ λ m,
|
||||
if h : n = m then isTrue (h ▸ rfl) else isFalse (λ h', UInt64.noConfusion h' (λ h', absurd h' h))
|
||||
UInt64.casesOn a $ fun n => UInt64.casesOn b $ fun m =>
|
||||
if h : n = m then isTrue (h ▸ rfl) else isFalse (fun h' => UInt64.noConfusion h' (fun h' => absurd h' h))
|
||||
|
||||
@[extern cpp inline "#1 < #2"]
|
||||
def UInt64.decLt (a b : UInt64) : Decidable (a < b) :=
|
||||
UInt64.casesOn a $ λ n, UInt64.casesOn b $ λ m,
|
||||
UInt64.casesOn a $ fun n => UInt64.casesOn b $ fun m =>
|
||||
inferInstanceAs (Decidable (n < m))
|
||||
|
||||
@[extern cpp inline "#1 <= #2"]
|
||||
def UInt64.decLe (a b : UInt64) : Decidable (a ≤ b) :=
|
||||
UInt64.casesOn a $ λ n, UInt64.casesOn b $ λ m,
|
||||
UInt64.casesOn a $ fun n => UInt64.casesOn b $ fun m =>
|
||||
inferInstanceAs (Decidable (n <= m))
|
||||
|
||||
instance : DecidableEq UInt64 := {decEq := UInt64.decEq}
|
||||
|
|
@ -290,17 +290,17 @@ instance : Inhabited USize := ⟨0⟩
|
|||
|
||||
@[extern cpp inline "#1 == #2"]
|
||||
def USize.decEq (a b : USize) : Decidable (a = b) :=
|
||||
USize.casesOn a $ λ n, USize.casesOn b $ λ m,
|
||||
if h : n = m then isTrue (h ▸ rfl) else isFalse (λ h', USize.noConfusion h' (λ h', absurd h' h))
|
||||
USize.casesOn a $ fun n => USize.casesOn b $ fun m =>
|
||||
if h : n = m then isTrue (h ▸ rfl) else isFalse (fun h' => USize.noConfusion h' (fun h' => absurd h' h))
|
||||
|
||||
@[extern cpp inline "#1 < #2"]
|
||||
def USize.decLt (a b : USize) : Decidable (a < b) :=
|
||||
USize.casesOn a $ λ n, USize.casesOn b $ λ m,
|
||||
USize.casesOn a $ fun n => USize.casesOn b $ fun m =>
|
||||
inferInstanceAs (Decidable (n < m))
|
||||
|
||||
@[extern cpp inline "#1 <= #2"]
|
||||
def USize.decLe (a b : USize) : Decidable (a ≤ b) :=
|
||||
USize.casesOn a $ λ n, USize.casesOn b $ λ m,
|
||||
USize.casesOn a $ fun n => USize.casesOn b $ fun m =>
|
||||
inferInstanceAs (Decidable (n <= m))
|
||||
|
||||
instance : DecidableEq USize := {decEq := USize.decEq}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ bfix1 base rec usizeSz
|
|||
fixCore1 base rec
|
||||
|
||||
@[inline] def fix1 {α β : Type u} [Inhabited β] (rec : (α → β) → α → β) : α → β :=
|
||||
fixCore1 (λ _, default β) rec
|
||||
fixCore1 (fun _ => default β) rec
|
||||
|
||||
@[inline] def fix {α β : Type u} [Inhabited β] (rec : (α → β) → α → β) : α → β :=
|
||||
fixCore1 (λ _, default β) rec
|
||||
fixCore1 (fun _ => default β) rec
|
||||
|
||||
def bfix2 {α₁ α₂ β : Type u} (base : α₁ → α₂ → β) (rec : (α₁ → α₂ → β) → α₁ → α₂ → β) : Nat → α₁ → α₂ → β
|
||||
| 0 a₁ a₂ := base a₁ a₂
|
||||
|
|
@ -33,7 +33,7 @@ def fixCore2 {α₁ α₂ β : Type u} (base : α₁ → α₂ → β) (rec : (
|
|||
bfix2 base rec usizeSz
|
||||
|
||||
@[inline] def fix2 {α₁ α₂ β : Type u} [Inhabited β] (rec : (α₁ → α₂ → β) → α₁ → α₂ → β) : α₁ → α₂ → β :=
|
||||
fixCore2 (λ _ _, default β) rec
|
||||
fixCore2 (fun _ _ => default β) rec
|
||||
|
||||
def bfix3 {α₁ α₂ α₃ β : Type u} (base : α₁ → α₂ → α₃ → β) (rec : (α₁ → α₂ → α₃ → β) → α₁ → α₂ → α₃ → β) : Nat → α₁ → α₂ → α₃ → β
|
||||
| 0 a₁ a₂ a₃ := base a₁ a₂ a₃
|
||||
|
|
@ -44,7 +44,7 @@ def fixCore3 {α₁ α₂ α₃ β : Type u} (base : α₁ → α₂ → α₃
|
|||
bfix3 base rec usizeSz
|
||||
|
||||
@[inline] def fix3 {α₁ α₂ α₃ β : Type u} [Inhabited β] (rec : (α₁ → α₂ → α₃ → β) → α₁ → α₂ → α₃ → β) : α₁ → α₂ → α₃ → β :=
|
||||
fixCore3 (λ _ _ _, default β) rec
|
||||
fixCore3 (fun _ _ _ => default β) rec
|
||||
|
||||
def bfix4 {α₁ α₂ α₃ α₄ β : Type u} (base : α₁ → α₂ → α₃ → α₄ → β) (rec : (α₁ → α₂ → α₃ → α₄ → β) → α₁ → α₂ → α₃ → α₄ → β) : Nat → α₁ → α₂ → α₃ → α₄ → β
|
||||
| 0 a₁ a₂ a₃ a₄ := base a₁ a₂ a₃ a₄
|
||||
|
|
@ -55,7 +55,7 @@ def fixCore4 {α₁ α₂ α₃ α₄ β : Type u} (base : α₁ → α₂ →
|
|||
bfix4 base rec usizeSz
|
||||
|
||||
@[inline] def fix4 {α₁ α₂ α₃ α₄ β : Type u} [Inhabited β] (rec : (α₁ → α₂ → α₃ → α₄ → β) → α₁ → α₂ → α₃ → α₄ → β) : α₁ → α₂ → α₃ → α₄ → β :=
|
||||
fixCore4 (λ _ _ _ _, default β) rec
|
||||
fixCore4 (fun _ _ _ _ => default β) rec
|
||||
|
||||
def bfix5 {α₁ α₂ α₃ α₄ α₅ β : Type u} (base : α₁ → α₂ → α₃ → α₄ → α₅ → β) (rec : (α₁ → α₂ → α₃ → α₄ → α₅ → β) → α₁ → α₂ → α₃ → α₄ → α₅ → β) : Nat → α₁ → α₂ → α₃ → α₄ → α₅ → β
|
||||
| 0 a₁ a₂ a₃ a₄ a₅ := base a₁ a₂ a₃ a₄ a₅
|
||||
|
|
@ -66,7 +66,7 @@ def fixCore5 {α₁ α₂ α₃ α₄ α₅ β : Type u} (base : α₁ → α₂
|
|||
bfix5 base rec usizeSz
|
||||
|
||||
@[inline] def fix5 {α₁ α₂ α₃ α₄ α₅ β : Type u} [Inhabited β] (rec : (α₁ → α₂ → α₃ → α₄ → α₅ → β) → α₁ → α₂ → α₃ → α₄ → α₅ → β) : α₁ → α₂ → α₃ → α₄ → α₅ → β :=
|
||||
fixCore5 (λ _ _ _ _ _, default β) rec
|
||||
fixCore5 (fun _ _ _ _ _ => default β) rec
|
||||
|
||||
def bfix6 {α₁ α₂ α₃ α₄ α₅ α₆ β : Type u} (base : α₁ → α₂ → α₃ → α₄ → α₅ → α₆ → β) (rec : (α₁ → α₂ → α₃ → α₄ → α₅ → α₆ → β) → α₁ → α₂ → α₃ → α₄ → α₅ → α₆ → β) : Nat → α₁ → α₂ → α₃ → α₄ → α₅ → α₆ → β
|
||||
| 0 a₁ a₂ a₃ a₄ a₅ a₆ := base a₁ a₂ a₃ a₄ a₅ a₆
|
||||
|
|
@ -77,4 +77,4 @@ def fixCore6 {α₁ α₂ α₃ α₄ α₅ α₆ β : Type u} (base : α₁ →
|
|||
bfix6 base rec usizeSz
|
||||
|
||||
@[inline] def fix6 {α₁ α₂ α₃ α₄ α₅ α₆ β : Type u} [Inhabited β] (rec : (α₁ → α₂ → α₃ → α₄ → α₅ → α₆ → β) → α₁ → α₂ → α₃ → α₄ → α₅ → α₆ → β) : α₁ → α₂ → α₃ → α₄ → α₅ → α₆ → β :=
|
||||
fixCore6 (λ _ _ _ _ _ _, default β) rec
|
||||
fixCore6 (fun _ _ _ _ _ _ => default β) rec
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ do b ← h.read 1,
|
|||
-- h.putStr s *> h.putStr "\n"
|
||||
|
||||
def handle.readToEnd (h : handle) : m String :=
|
||||
Prim.liftIO $ Prim.iterate "" $ λ r, do
|
||||
Prim.liftIO $ Prim.iterate "" $ fun r => do
|
||||
done ← h.isEof;
|
||||
if done
|
||||
then pure (Sum.inr r) -- stop
|
||||
|
|
@ -256,11 +256,11 @@ class HasEval (α : Type u) :=
|
|||
(eval : α → IO Unit)
|
||||
|
||||
instance HasRepr.HasEval {α : Type u} [HasRepr α] : HasEval α :=
|
||||
⟨λ a, IO.println (repr a)⟩
|
||||
⟨fun a => IO.println (repr a)⟩
|
||||
|
||||
instance IO.HasEval {α : Type} [HasEval α] : HasEval (IO α) :=
|
||||
⟨λ x, do a ← x; HasEval.eval a⟩
|
||||
⟨fun x => do a ← x; HasEval.eval a⟩
|
||||
|
||||
-- special case: do not print `()`
|
||||
instance IOUnit.HasEval : HasEval (IO Unit) :=
|
||||
⟨λ x, x⟩
|
||||
⟨fun x => x⟩
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ end ScopeManagerState
|
|||
def regScopeManagerExtension : IO (SimplePersistentEnvExtension Name ScopeManagerState) :=
|
||||
registerSimplePersistentEnvExtension {
|
||||
name := `scopes,
|
||||
addImportedFn := λ as, mkStateFromImportedEntries ScopeManagerState.saveNamespace {} as,
|
||||
addEntryFn := λ s n, { allNamespaces := s.allNamespaces.insert n, .. s },
|
||||
addImportedFn := fun as => mkStateFromImportedEntries ScopeManagerState.saveNamespace {} as,
|
||||
addEntryFn := fun s n => { allNamespaces := s.allNamespaces.insert n, .. s },
|
||||
}
|
||||
|
||||
@[init regScopeManagerExtension]
|
||||
|
|
@ -76,7 +76,7 @@ def toValidNamespace (env : Environment) (n : Name) : Option Name :=
|
|||
let s := scopeManagerExt.getState env;
|
||||
if s.allNamespaces.contains n then some n
|
||||
else s.namespaces.foldl
|
||||
(λ r ns, match r with
|
||||
(fun r ns => match r with
|
||||
| some _ := r
|
||||
| none :=
|
||||
let c := ns ++ n;
|
||||
|
|
@ -95,7 +95,7 @@ def pushScopeCore (env : Environment) (header : Name) (isNamespace : Bool) : Env
|
|||
let ns := env.getNamespace;
|
||||
let newNs := if isNamespace then ns ++ header else ns;
|
||||
let env := env.registerNamespaceAux newNs;
|
||||
let env := scopeManagerExt.modifyState env $ λ s,
|
||||
let env := scopeManagerExt.modifyState env $ fun s =>
|
||||
{ headers := header :: s.headers,
|
||||
namespaces := newNs :: s.namespaces,
|
||||
isNamespace := isNamespace :: s.isNamespace,
|
||||
|
|
@ -104,7 +104,7 @@ env
|
|||
|
||||
def popScopeCore (env : Environment) : Environment :=
|
||||
if env.getNamespaces.isEmpty then env
|
||||
else scopeManagerExt.modifyState env $ λ s,
|
||||
else scopeManagerExt.modifyState env $ fun s =>
|
||||
{ headers := s.headers.tail,
|
||||
namespaces := s.namespaces.tail,
|
||||
isNamespace := s.isNamespace.tail,
|
||||
|
|
@ -129,7 +129,7 @@ structure AttributeImpl :=
|
|||
(applicationTime := AttributeApplicationTime.afterTypeChecking)
|
||||
|
||||
instance AttributeImpl.inhabited : Inhabited AttributeImpl :=
|
||||
⟨{ name := default _, descr := default _, add := λ env _ _ _, pure env }⟩
|
||||
⟨{ name := default _, descr := default _, add := fun env _ _ _ => pure env }⟩
|
||||
|
||||
def mkAttributeMapRef : IO (IO.Ref (HashMap Name AttributeImpl)) :=
|
||||
IO.mkRef {}
|
||||
|
|
@ -149,8 +149,8 @@ do m ← attributeMapRef.get;
|
|||
when (m.contains attr.name) $ throw (IO.userError ("invalid attribute declaration, '" ++ toString attr.name ++ "' has already been used"));
|
||||
initializing ← IO.initializing;
|
||||
unless initializing $ throw (IO.userError ("failed to register attribute, attributes can only be registered during initialization"));
|
||||
attributeMapRef.modify (λ m, m.insert attr.name attr);
|
||||
attributeArrayRef.modify (λ attrs, attrs.push attr)
|
||||
attributeMapRef.modify (fun m => m.insert attr.name attr);
|
||||
attributeArrayRef.modify (fun attrs => attrs.push attr)
|
||||
|
||||
/- Return true iff `n` is the name of a registered attribute. -/
|
||||
@[export lean.is_attribute_core]
|
||||
|
|
@ -159,7 +159,7 @@ do m ← attributeMapRef.get; pure (m.contains n)
|
|||
|
||||
/- Return the name of all registered attributes. -/
|
||||
def getAttributeNames : IO (List Name) :=
|
||||
do m ← attributeMapRef.get; pure $ m.fold (λ r n _, n::r) []
|
||||
do m ← attributeMapRef.get; pure $ m.fold (fun r n _ => n::r) []
|
||||
|
||||
def getAttributeImpl (attrName : Name) : IO AttributeImpl :=
|
||||
do m ← attributeMapRef.get;
|
||||
|
|
@ -218,7 +218,7 @@ do attr ← getAttributeImpl attrName;
|
|||
@[export lean.activate_scoped_attributes_core]
|
||||
def activateScopedAttributes (env : Environment) (scope : Name) : IO Environment :=
|
||||
do attrs ← attributeArrayRef.get;
|
||||
attrs.mfoldl (λ env attr, attr.activateScoped env scope) env
|
||||
attrs.mfoldl (fun env attr => attr.activateScoped env scope) env
|
||||
|
||||
/- We use this function to implement commands `namespace foo` and `section foo`.
|
||||
It activates scoped attributes in the new resulting namespace. -/
|
||||
|
|
@ -227,14 +227,14 @@ def pushScope (env : Environment) (header : Name) (isNamespace : Bool) : IO Envi
|
|||
do let env := env.pushScopeCore header isNamespace;
|
||||
let ns := env.getNamespace;
|
||||
attrs ← attributeArrayRef.get;
|
||||
attrs.mfoldl (λ env attr, do env ← attr.pushScope env; if isNamespace then attr.activateScoped env ns else pure env) env
|
||||
attrs.mfoldl (fun env attr => do env ← attr.pushScope env; if isNamespace then attr.activateScoped env ns else pure env) env
|
||||
|
||||
/- We use this function to implement commands `end foo` for closing namespaces and sections. -/
|
||||
@[export lean.pop_scope_core]
|
||||
def popScope (env : Environment) : IO Environment :=
|
||||
do let env := env.popScopeCore;
|
||||
attrs ← attributeArrayRef.get;
|
||||
attrs.mfoldl (λ env attr, attr.popScope env) env
|
||||
attrs.mfoldl (fun env attr => attr.popScope env) env
|
||||
|
||||
end Environment
|
||||
|
||||
|
|
@ -250,21 +250,21 @@ structure TagAttribute :=
|
|||
(attr : AttributeImpl)
|
||||
(ext : PersistentEnvExtension Name NameSet)
|
||||
|
||||
def registerTagAttribute (name : Name) (descr : String) (validate : Environment → Name → Except String Unit := λ _ _, Except.ok ()) : IO TagAttribute :=
|
||||
def registerTagAttribute (name : Name) (descr : String) (validate : Environment → Name → Except String Unit := fun _ _ => Except.ok ()) : IO TagAttribute :=
|
||||
do
|
||||
ext : PersistentEnvExtension Name NameSet ← registerPersistentEnvExtension {
|
||||
name := name,
|
||||
addImportedFn := λ _, {},
|
||||
addEntryFn := λ (s : NameSet) n, s.insert n,
|
||||
exportEntriesFn := λ es,
|
||||
let r : Array Name := es.fold (λ a e, a.push e) Array.empty;
|
||||
addImportedFn := fun _ => {},
|
||||
addEntryFn := fun (s : NameSet) n => s.insert n,
|
||||
exportEntriesFn := fun es =>
|
||||
let r : Array Name := es.fold (fun a e => a.push e) Array.empty;
|
||||
r.qsort Name.quickLt,
|
||||
statsFn := λ s, "tag attribute" ++ Format.line ++ "number of local entries: " ++ format s.size
|
||||
statsFn := fun s => "tag attribute" ++ Format.line ++ "number of local entries: " ++ format s.size
|
||||
};
|
||||
let attrImpl : AttributeImpl := {
|
||||
name := name,
|
||||
descr := descr,
|
||||
add := λ env decl args persistent, do
|
||||
add := fun env decl args persistent => do
|
||||
unless args.isMissing $ throw (IO.userError ("invalid attribute '" ++ toString name ++ "', unexpected argument"));
|
||||
unless persistent $ throw (IO.userError ("invalid attribute '" ++ toString name ++ "', must be persistent"));
|
||||
unless (env.getModuleIdxFor decl).isNone $
|
||||
|
|
@ -299,21 +299,21 @@ structure ParametricAttribute (α : Type) :=
|
|||
|
||||
def registerParametricAttribute {α : Type} [Inhabited α] (name : Name) (descr : String)
|
||||
(getParam : Environment → Name → Syntax → Except String α)
|
||||
(afterSet : Environment → Name → α → Except String Environment := λ env _ _, Except.ok env) : IO (ParametricAttribute α) :=
|
||||
(afterSet : Environment → Name → α → Except String Environment := fun env _ _ => Except.ok env) : IO (ParametricAttribute α) :=
|
||||
do
|
||||
ext : PersistentEnvExtension (Name × α) (NameMap α) ← registerPersistentEnvExtension {
|
||||
name := name,
|
||||
addImportedFn := λ _, {},
|
||||
addEntryFn := λ (s : NameMap α) (p : Name × α), s.insert p.1 p.2,
|
||||
exportEntriesFn := λ m,
|
||||
let r : Array (Name × α) := m.fold (λ a n p, a.push (n, p)) Array.empty;
|
||||
r.qsort (λ a b, Name.quickLt a.1 b.1),
|
||||
statsFn := λ s, "parametric attribute" ++ Format.line ++ "number of local entries: " ++ format s.size
|
||||
addImportedFn := fun _ => {},
|
||||
addEntryFn := fun (s : NameMap α) (p : Name × α) => s.insert p.1 p.2,
|
||||
exportEntriesFn := fun m =>
|
||||
let r : Array (Name × α) := m.fold (fun a n p => a.push (n, p)) Array.empty;
|
||||
r.qsort (fun a b => Name.quickLt a.1 b.1),
|
||||
statsFn := fun s => "parametric attribute" ++ Format.line ++ "number of local entries: " ++ format s.size
|
||||
};
|
||||
let attrImpl : AttributeImpl := {
|
||||
name := name,
|
||||
descr := descr,
|
||||
add := λ env decl args persistent, do
|
||||
add := fun env decl args persistent => do
|
||||
unless persistent $ throw (IO.userError ("invalid attribute '" ++ toString name ++ "', must be persistent"));
|
||||
unless (env.getModuleIdxFor decl).isNone $
|
||||
throw (IO.userError ("invalid attribute '" ++ toString name ++ "', declaration is in an imported module"));
|
||||
|
|
@ -335,7 +335,7 @@ instance {α : Type} : Inhabited (ParametricAttribute α) := ⟨{attr := default
|
|||
def getParam {α : Type} [Inhabited α] (attr : ParametricAttribute α) (env : Environment) (decl : Name) : Option α :=
|
||||
match env.getModuleIdxFor decl with
|
||||
| some modIdx :=
|
||||
match (attr.ext.getModuleEntries env modIdx).binSearch (decl, default _) (λ a b, Name.quickLt a.1 b.1) with
|
||||
match (attr.ext.getModuleEntries env modIdx).binSearch (decl, default _) (fun a b => Name.quickLt a.1 b.1) with
|
||||
| some (_, val) := some val
|
||||
| none := none
|
||||
| none := (attr.ext.getState env).find decl
|
||||
|
|
@ -358,21 +358,21 @@ structure EnumAttributes (α : Type) :=
|
|||
(attrs : List AttributeImpl)
|
||||
(ext : PersistentEnvExtension (Name × α) (NameMap α))
|
||||
|
||||
def registerEnumAttributes {α : Type} [Inhabited α] (extName : Name) (attrDescrs : List (Name × String × α)) (validate : Environment → Name → α → Except String Unit := λ _ _ _, Except.ok ()) : IO (EnumAttributes α) :=
|
||||
def registerEnumAttributes {α : Type} [Inhabited α] (extName : Name) (attrDescrs : List (Name × String × α)) (validate : Environment → Name → α → Except String Unit := fun _ _ _ => Except.ok ()) : IO (EnumAttributes α) :=
|
||||
do
|
||||
ext : PersistentEnvExtension (Name × α) (NameMap α) ← registerPersistentEnvExtension {
|
||||
name := extName,
|
||||
addImportedFn := λ _, {},
|
||||
addEntryFn := λ (s : NameMap α) (p : Name × α), s.insert p.1 p.2,
|
||||
exportEntriesFn := λ m,
|
||||
let r : Array (Name × α) := m.fold (λ a n p, a.push (n, p)) Array.empty;
|
||||
r.qsort (λ a b, Name.quickLt a.1 b.1),
|
||||
statsFn := λ s, "enumeration attribute extension" ++ Format.line ++ "number of local entries: " ++ format s.size
|
||||
addImportedFn := fun _ => {},
|
||||
addEntryFn := fun (s : NameMap α) (p : Name × α) => s.insert p.1 p.2,
|
||||
exportEntriesFn := fun m =>
|
||||
let r : Array (Name × α) := m.fold (fun a n p => a.push (n, p)) Array.empty;
|
||||
r.qsort (fun a b => Name.quickLt a.1 b.1),
|
||||
statsFn := fun s => "enumeration attribute extension" ++ Format.line ++ "number of local entries: " ++ format s.size
|
||||
};
|
||||
let attrs := attrDescrs.map $ λ ⟨name, descr, val⟩, { AttributeImpl .
|
||||
let attrs := attrDescrs.map $ fun ⟨name, descr, val⟩ => { AttributeImpl .
|
||||
name := name,
|
||||
descr := descr,
|
||||
add := λ env decl args persistent, do
|
||||
add := fun env decl args persistent => do
|
||||
unless persistent $ throw (IO.userError ("invalid attribute '" ++ toString name ++ "', must be persistent"));
|
||||
unless (env.getModuleIdxFor decl).isNone $
|
||||
throw (IO.userError ("invalid attribute '" ++ toString name ++ "', declaration is in an imported module"));
|
||||
|
|
@ -390,7 +390,7 @@ instance {α : Type} : Inhabited (EnumAttributes α) := ⟨{attrs := [], ext :=
|
|||
def getValue {α : Type} [Inhabited α] (attr : EnumAttributes α) (env : Environment) (decl : Name) : Option α :=
|
||||
match env.getModuleIdxFor decl with
|
||||
| some modIdx :=
|
||||
match (attr.ext.getModuleEntries env modIdx).binSearch (decl, default _) (λ a b, Name.quickLt a.1 b.1) with
|
||||
match (attr.ext.getModuleEntries env modIdx).binSearch (decl, default _) (fun a b => Name.quickLt a.1 b.1) with
|
||||
| some (_, val) := some val
|
||||
| none := none
|
||||
| none := (attr.ext.getState env).find decl
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ def mkClassExtension : IO (SimplePersistentEnvExtension ClassEntry ClassState) :
|
|||
registerSimplePersistentEnvExtension {
|
||||
name := `classExt,
|
||||
addEntryFn := ClassState.addEntry,
|
||||
addImportedFn := λ es, (mkStateFromImportedEntries ClassState.addEntry {} es).switch
|
||||
addImportedFn := fun es => (mkStateFromImportedEntries ClassState.addEntry {} es).switch
|
||||
}
|
||||
|
||||
@[init mkClassExtension]
|
||||
|
|
@ -124,7 +124,7 @@ match env.find instName with
|
|||
registerAttribute {
|
||||
name := `class,
|
||||
descr := "type class",
|
||||
add := λ env decl args persistent, do
|
||||
add := fun env decl args persistent => do
|
||||
unless args.isMissing $ throw (IO.userError ("invalid attribute 'class', unexpected argument"));
|
||||
unless persistent $ throw (IO.userError ("invalid attribute 'class', must be persistent"));
|
||||
IO.ofExcept (addClass env decl)
|
||||
|
|
@ -134,7 +134,7 @@ registerAttribute {
|
|||
registerAttribute {
|
||||
name := `instance,
|
||||
descr := "type class instance",
|
||||
add := λ env decl args persistent, do
|
||||
add := fun env decl args persistent => do
|
||||
unless args.isMissing $ throw (IO.userError ("invalid attribute 'instance', unexpected argument"));
|
||||
unless persistent $ throw (IO.userError ("invalid attribute 'instance', must be persistent"));
|
||||
IO.ofExcept (addInstance env decl)
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ abbrev ClosedTermCache := SMap Expr Name Expr.quickLt
|
|||
def mkClosedTermCacheExtension : IO (SimplePersistentEnvExtension (Expr × Name) ClosedTermCache) :=
|
||||
registerSimplePersistentEnvExtension {
|
||||
name := `closedTermCache,
|
||||
addImportedFn := λ as,
|
||||
let cache : ClosedTermCache := mkStateFromImportedEntries (λ s (p : Expr × Name), s.insert p.1 p.2) {} as;
|
||||
addImportedFn := fun as =>
|
||||
let cache : ClosedTermCache := mkStateFromImportedEntries (fun s (p : Expr × Name) => s.insert p.1 p.2) {} as;
|
||||
cache.switch,
|
||||
addEntryFn := λ s ⟨e, n⟩, s.insert e n
|
||||
addEntryFn := fun s ⟨e, n⟩ => s.insert e n
|
||||
}
|
||||
|
||||
@[init mkClosedTermCacheExtension]
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ def numScalarTypes : List NumScalarTypeInfo :=
|
|||
{id := `USize, nbits := System.platform.nbits}]
|
||||
|
||||
def isOfNat (fn : Name) : Bool :=
|
||||
numScalarTypes.any (λ info, info.ofNatFn = fn)
|
||||
numScalarTypes.any (fun info => info.ofNatFn = fn)
|
||||
|
||||
def isToNat (fn : Name) : Bool :=
|
||||
numScalarTypes.any (λ info, info.toNatFn = fn)
|
||||
numScalarTypes.any (fun info => info.toNatFn = fn)
|
||||
|
||||
def getInfoFromFn (fn : Name) : List NumScalarTypeInfo → Option NumScalarTypeInfo
|
||||
| [] := none
|
||||
|
|
@ -63,18 +63,18 @@ do n₁ ← getNumLit a₁;
|
|||
info ← getInfoFromVal a₁;
|
||||
pure $ mkUIntLit info (fn info beforeErasure n₁ n₂)
|
||||
|
||||
def foldUIntAdd := foldBinUInt $ λ _ _, HasAdd.add
|
||||
def foldUIntMul := foldBinUInt $ λ _ _, HasMul.mul
|
||||
def foldUIntDiv := foldBinUInt $ λ _ _, HasDiv.div
|
||||
def foldUIntMod := foldBinUInt $ λ _ _, HasMod.mod
|
||||
def foldUIntSub := foldBinUInt $ λ info _ a b, (a + (info.size - b))
|
||||
def foldUIntAdd := foldBinUInt $ fun _ _ => HasAdd.add
|
||||
def foldUIntMul := foldBinUInt $ fun _ _ => HasMul.mul
|
||||
def foldUIntDiv := foldBinUInt $ fun _ _ => HasDiv.div
|
||||
def foldUIntMod := foldBinUInt $ fun _ _ => HasMod.mod
|
||||
def foldUIntSub := foldBinUInt $ fun info _ a b => (a + (info.size - b))
|
||||
|
||||
def preUIntBinFoldFns : List (Name × BinFoldFn) :=
|
||||
[(`add, foldUIntAdd), (`mul, foldUIntMul), (`div, foldUIntDiv),
|
||||
(`mod, foldUIntMod), (`sub, foldUIntSub)]
|
||||
|
||||
def uintBinFoldFns : List (Name × BinFoldFn) :=
|
||||
numScalarTypes.foldl (λ r info, r ++ (preUIntBinFoldFns.map (λ ⟨suffix, fn⟩, (info.id ++ suffix, fn)))) []
|
||||
numScalarTypes.foldl (fun r info => r ++ (preUIntBinFoldFns.map (fun ⟨suffix, fn⟩ => (info.id ++ suffix, fn)))) []
|
||||
|
||||
def foldNatBinOp (fn : Nat → Nat → Nat) (a₁ a₂ : Expr) : Option Expr :=
|
||||
do n₁ ← getNumLit a₁;
|
||||
|
|
@ -109,9 +109,9 @@ do n₁ ← getNumLit a₁;
|
|||
n₂ ← getNumLit a₂;
|
||||
pure $ toDecidableExpr beforeErasure (mkPred a₁ a₂) (fn n₁ n₂)
|
||||
|
||||
def foldNatDecEq := foldNatBinPred mkNatEq (λ a b, a = b)
|
||||
def foldNatDecLt := foldNatBinPred mkNatLt (λ a b, a < b)
|
||||
def foldNatDecLe := foldNatBinPred mkNatLe (λ a b, a ≤ b)
|
||||
def foldNatDecEq := foldNatBinPred mkNatEq (fun a b => a = b)
|
||||
def foldNatDecLt := foldNatBinPred mkNatLt (fun a b => a < b)
|
||||
def foldNatDecLe := foldNatBinPred mkNatLe (fun a b => a ≤ b)
|
||||
|
||||
def natFoldFns : List (Name × BinFoldFn) :=
|
||||
[(`Nat.add, foldNatAdd),
|
||||
|
|
@ -171,7 +171,7 @@ do n ← getNumLit a;
|
|||
pure $ Expr.lit (Literal.natVal n)
|
||||
|
||||
def uintFoldToNatFns : List (Name × UnFoldFn) :=
|
||||
numScalarTypes.foldl (λ r info, (info.toNatFn, foldToNat) :: r) []
|
||||
numScalarTypes.foldl (fun r info => (info.toNatFn, foldToNat) :: r) []
|
||||
|
||||
def unFoldFns : List (Name × UnFoldFn) :=
|
||||
[(`Nat.succ, foldNatSucc),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Lean
|
|||
|
||||
private def isValidCppId (id : String) : Bool :=
|
||||
let first := id.get 0;
|
||||
first.isAlpha && (id.toSubstring.drop 1).all (λ c, c.isAlpha || c.isDigit || c == '_')
|
||||
first.isAlpha && (id.toSubstring.drop 1).all (fun c => c.isAlpha || c.isDigit || c == '_')
|
||||
|
||||
private def isValidCppName : Name → Bool
|
||||
| (Name.mkString Name.anonymous s) := isValidCppId s
|
||||
|
|
@ -18,7 +18,7 @@ private def isValidCppName : Name → Bool
|
|||
| _ := false
|
||||
|
||||
def mkExportAttr : IO (ParametricAttribute Name) :=
|
||||
registerParametricAttribute `export "name to be used by code generators" $ λ _ _ stx,
|
||||
registerParametricAttribute `export "name to be used by code generators" $ fun _ _ stx =>
|
||||
match attrParamSyntaxToIdentifier stx with
|
||||
| some exportName :=
|
||||
if isValidCppName exportName then Except.ok exportName
|
||||
|
|
|
|||
|
|
@ -82,8 +82,8 @@ constant addExtern (env : Environment) (n : Name) : ExceptT String Id Environmen
|
|||
|
||||
def mkExternAttr : IO (ParametricAttribute ExternAttrData) :=
|
||||
registerParametricAttribute `extern "builtin and foreign functions"
|
||||
(λ _ _, syntaxToExternAttrData)
|
||||
(λ env declName _,
|
||||
(fun _ _ => syntaxToExternAttrData)
|
||||
(fun env declName _ =>
|
||||
if env.isProjectionFn declName || env.isConstructor declName then
|
||||
addExtern env declName
|
||||
else
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Lean
|
|||
namespace Compiler
|
||||
|
||||
def mkImplementedByAttr : IO (ParametricAttribute Name) :=
|
||||
registerParametricAttribute `implementedBy "name of the Lean (probably unsafe) function that implements opaque constant" $ λ env declName stx,
|
||||
registerParametricAttribute `implementedBy "name of the Lean (probably unsafe) function that implements opaque constant" $ fun env declName stx =>
|
||||
match env.find declName with
|
||||
| none := Except.error "unknown declaration"
|
||||
| some decl :=
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ match getIOTypeArg type with
|
|||
| _ := false
|
||||
|
||||
def mkInitAttr : IO (ParametricAttribute Name) :=
|
||||
registerParametricAttribute `init "initialization procedure for global references" $ λ env declName stx,
|
||||
registerParametricAttribute `init "initialization procedure for global references" $ fun env declName stx =>
|
||||
match env.find declName with
|
||||
| none := Except.error "unknown declaration"
|
||||
| some decl :=
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ registerEnumAttributes `inlineAttrs
|
|||
(`inlineIfReduce, "mark definition to be inlined when resultant term after reduction is not a `cases_on` application", InlineAttributeKind.inlineIfReduce),
|
||||
(`noinline, "mark definition to never be inlined", InlineAttributeKind.noinline),
|
||||
(`macroInline, "mark definition to always be inlined before ANF conversion", InlineAttributeKind.macroInline)]
|
||||
(λ env declName _, checkIsDefinition env declName)
|
||||
(fun env declName _ => checkIsDefinition env declName)
|
||||
|
||||
@[init mkInlineAttrs]
|
||||
constant inlineAttrs : EnumAttributes InlineAttributeKind := default _
|
||||
|
|
|
|||
|
|
@ -33,17 +33,17 @@ structure JoinPointId :=
|
|||
abbrev Index.lt (a b : Index) : Bool := a < b
|
||||
|
||||
namespace VarId
|
||||
instance : HasBeq VarId := ⟨λ a b, a.idx == b.idx⟩
|
||||
instance : HasToString VarId := ⟨λ a, "x_" ++ toString a.idx⟩
|
||||
instance : HasFormat VarId := ⟨λ a, toString a⟩
|
||||
instance : Hashable VarId := ⟨λ a, hash a.idx⟩
|
||||
instance : HasBeq VarId := ⟨fun a b => a.idx == b.idx⟩
|
||||
instance : HasToString VarId := ⟨fun a => "x_" ++ toString a.idx⟩
|
||||
instance : HasFormat VarId := ⟨fun a => toString a⟩
|
||||
instance : Hashable VarId := ⟨fun a => hash a.idx⟩
|
||||
end VarId
|
||||
|
||||
namespace JoinPointId
|
||||
instance : HasBeq JoinPointId := ⟨λ a b, a.idx == b.idx⟩
|
||||
instance : HasToString JoinPointId := ⟨λ a, "block_" ++ toString a.idx⟩
|
||||
instance : HasFormat JoinPointId := ⟨λ a, toString a⟩
|
||||
instance : Hashable JoinPointId := ⟨λ a, hash a.idx⟩
|
||||
instance : HasBeq JoinPointId := ⟨fun a b => a.idx == b.idx⟩
|
||||
instance : HasToString JoinPointId := ⟨fun a => "block_" ++ toString a.idx⟩
|
||||
instance : HasFormat JoinPointId := ⟨fun a => toString a⟩
|
||||
instance : Hashable JoinPointId := ⟨fun a => hash a.idx⟩
|
||||
end JoinPointId
|
||||
|
||||
abbrev MData := KVMap
|
||||
|
|
@ -347,12 +347,12 @@ def reshape (bs : Array FnBody) (term : FnBody) : FnBody :=
|
|||
reshapeAux bs bs.size term
|
||||
|
||||
@[inline] def modifyJPs (bs : Array FnBody) (f : FnBody → FnBody) : Array FnBody :=
|
||||
bs.map $ λ b, match b with
|
||||
bs.map $ fun b => match b with
|
||||
| FnBody.jdecl j xs v k := FnBody.jdecl j xs (f v) k
|
||||
| other := other
|
||||
|
||||
@[inline] def mmodifyJPs {m : Type → Type} [Monad m] (bs : Array FnBody) (f : FnBody → m FnBody) : m (Array FnBody) :=
|
||||
bs.mmap $ λ b, match b with
|
||||
bs.mmap $ fun b => match b with
|
||||
| FnBody.jdecl j xs v k := do v ← f v; pure $ FnBody.jdecl j xs v k
|
||||
| other := pure other
|
||||
|
||||
|
|
@ -468,7 +468,7 @@ def Arg.alphaEqv (ρ : IndexRenaming) : Arg → Arg → Bool
|
|||
instance Arg.hasAeqv : HasAlphaEqv Arg := ⟨Arg.alphaEqv⟩
|
||||
|
||||
def args.alphaEqv (ρ : IndexRenaming) (args₁ args₂ : Array Arg) : Bool :=
|
||||
Array.isEqv args₁ args₂ (λ a b, aeqv ρ a b)
|
||||
Array.isEqv args₁ args₂ (fun a b => aeqv ρ a b)
|
||||
|
||||
instance args.hasAeqv : HasAlphaEqv (Array Arg) := ⟨args.alphaEqv⟩
|
||||
|
||||
|
|
@ -500,7 +500,7 @@ else none
|
|||
|
||||
def addParamsRename (ρ : IndexRenaming) (ps₁ ps₂ : Array Param) : Option IndexRenaming :=
|
||||
if ps₁.size != ps₂.size then none
|
||||
else Array.foldl₂ (λ ρ p₁ p₂, do ρ ← ρ; addParamRename ρ p₁ p₂) (some ρ) ps₁ ps₂
|
||||
else Array.foldl₂ (fun ρ p₁ p₂ => do ρ ← ρ; addParamRename ρ p₁ p₂) (some ρ) ps₁ ps₂
|
||||
|
||||
partial def FnBody.alphaEqv : IndexRenaming → FnBody → FnBody → Bool
|
||||
| ρ (FnBody.vdecl x₁ t₁ v₁ b₁) (FnBody.vdecl x₂ t₂ v₂ b₂) := t₁ == t₂ && aeqv ρ v₁ v₂ && FnBody.alphaEqv (addVarRename ρ x₁.idx x₂.idx) b₁ b₂
|
||||
|
|
@ -516,7 +516,7 @@ partial def FnBody.alphaEqv : IndexRenaming → FnBody → FnBody → Bool
|
|||
| ρ (FnBody.dec x₁ n₁ c₁ b₁) (FnBody.dec x₂ n₂ c₂ b₂) := aeqv ρ x₁ x₂ && n₁ == n₂ && c₁ == c₂ && FnBody.alphaEqv ρ b₁ b₂
|
||||
| ρ (FnBody.del x₁ b₁) (FnBody.del x₂ b₂) := aeqv ρ x₁ x₂ && FnBody.alphaEqv ρ b₁ b₂
|
||||
| ρ (FnBody.mdata m₁ b₁) (FnBody.mdata m₂ b₂) := m₁ == m₂ && FnBody.alphaEqv ρ b₁ b₂
|
||||
| ρ (FnBody.case n₁ x₁ alts₁) (FnBody.case n₂ x₂ alts₂) := n₁ == n₂ && aeqv ρ x₁ x₂ && Array.isEqv alts₁ alts₂ (λ alt₁ alt₂,
|
||||
| ρ (FnBody.case n₁ x₁ alts₁) (FnBody.case n₂ x₂ alts₂) := n₁ == n₂ && aeqv ρ x₁ x₂ && Array.isEqv alts₁ alts₂ (fun alt₁ alt₂ =>
|
||||
match alt₁, alt₂ with
|
||||
| Alt.ctor i₁ b₁, Alt.ctor i₂ b₂ := i₁ == i₂ && FnBody.alphaEqv ρ b₁ b₂
|
||||
| Alt.default b₁, Alt.default b₂ := FnBody.alphaEqv ρ b₁ b₂
|
||||
|
|
@ -531,7 +531,7 @@ FnBody.alphaEqv ∅ b₁ b₂
|
|||
|
||||
instance FnBody.HasBeq : HasBeq FnBody := ⟨FnBody.beq⟩
|
||||
|
||||
abbrev VarIdSet := RBTree VarId (λ x y, x.idx < y.idx)
|
||||
abbrev VarIdSet := RBTree VarId (fun x y => x.idx < y.idx)
|
||||
namespace VarIdSet
|
||||
instance : Inhabited VarIdSet := ⟨{}⟩
|
||||
end VarIdSet
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ end Key
|
|||
abbrev ParamMap := HashMap Key (Array Param)
|
||||
|
||||
def ParamMap.fmt (map : ParamMap) : Format :=
|
||||
let fmts := map.fold (λ fmt k ps,
|
||||
let fmts := map.fold (fun fmt k ps =>
|
||||
let k := match k with
|
||||
| Key.decl n := format n
|
||||
| Key.jp n id := format n ++ ":" ++ format id;
|
||||
|
|
@ -49,13 +49,13 @@ let fmts := map.fold (λ fmt k ps,
|
|||
"{" ++ (Format.nest 1 fmts) ++ "}"
|
||||
|
||||
instance : HasFormat ParamMap := ⟨ParamMap.fmt⟩
|
||||
instance : HasToString ParamMap := ⟨λ m, Format.pretty (format m)⟩
|
||||
instance : HasToString ParamMap := ⟨fun m => Format.pretty (format m)⟩
|
||||
|
||||
namespace InitParamMap
|
||||
|
||||
/- Mark parameters that take a reference as borrow -/
|
||||
def initBorrow (ps : Array Param) : Array Param :=
|
||||
ps.map $ λ p, { borrow := p.ty.isObj, .. p }
|
||||
ps.map $ fun p => { borrow := p.ty.isObj, .. p }
|
||||
|
||||
/- We do perform borrow inference for constants marked as `export`.
|
||||
Reason: we current write wrappers in C++ for using exported functions.
|
||||
|
|
@ -70,7 +70,7 @@ if exported then ps else initBorrow ps
|
|||
|
||||
partial def visitFnBody (fnid : FunId) : FnBody → State ParamMap Unit
|
||||
| (FnBody.jdecl j xs v b) := do
|
||||
modify $ λ m, m.insert (Key.jp fnid j) (initBorrow xs);
|
||||
modify $ fun m => m.insert (Key.jp fnid j) (initBorrow xs);
|
||||
visitFnBody v;
|
||||
visitFnBody b
|
||||
| e :=
|
||||
|
|
@ -79,10 +79,10 @@ partial def visitFnBody (fnid : FunId) : FnBody → State ParamMap Unit
|
|||
visitFnBody b
|
||||
|
||||
def visitDecls (env : Environment) (decls : Array Decl) : State ParamMap Unit :=
|
||||
decls.mfor $ λ decl, match decl with
|
||||
decls.mfor $ fun decl => match decl with
|
||||
| Decl.fdecl f xs _ b := do
|
||||
let exported := isExport env f;
|
||||
modify $ λ m, m.insert (Key.decl f) (initBorrowIfNotExported exported xs);
|
||||
modify $ fun m => m.insert (Key.decl f) (initBorrowIfNotExported exported xs);
|
||||
visitFnBody f b
|
||||
| _ := pure ()
|
||||
end InitParamMap
|
||||
|
|
@ -109,7 +109,7 @@ partial def visitFnBody : FnBody → FunId → ParamMap → FnBody
|
|||
instr.setBody b
|
||||
|
||||
def visitDecls (decls : Array Decl) (map : ParamMap) : Array Decl :=
|
||||
decls.map $ λ decl, match decl with
|
||||
decls.map $ fun decl => match decl with
|
||||
| Decl.fdecl f xs ty b :=
|
||||
let b := visitFnBody b f map;
|
||||
match map.find (Key.decl f) with
|
||||
|
|
@ -120,7 +120,7 @@ decls.map $ λ decl, match decl with
|
|||
end ApplyParamMap
|
||||
|
||||
def applyParamMap (decls : Array Decl) (map : ParamMap) : Array Decl :=
|
||||
-- dbgTrace ("applyParamMap " ++ toString map) $ λ _,
|
||||
-- dbgTrace ("applyParamMap " ++ toString map) $ fun _ =>
|
||||
ApplyParamMap.visitDecls decls map
|
||||
|
||||
structure BorrowInfCtx :=
|
||||
|
|
@ -139,11 +139,11 @@ structure BorrowInfState :=
|
|||
abbrev M := ReaderT BorrowInfCtx (State BorrowInfState)
|
||||
|
||||
def markModifiedParamMap : M Unit :=
|
||||
modify $ λ s, { modifiedParamMap := true, .. s }
|
||||
modify $ fun s => { modifiedParamMap := true, .. s }
|
||||
|
||||
def ownVar (x : VarId) : M Unit :=
|
||||
-- dbgTrace ("ownVar " ++ toString x) $ λ _,
|
||||
modify $ λ s,
|
||||
-- dbgTrace ("ownVar " ++ toString x) $ fun _ =>
|
||||
modify $ fun s =>
|
||||
if s.owned.contains x.idx then s
|
||||
else { owned := s.owned.insert x.idx, modifiedOwned := true, .. s }
|
||||
|
||||
|
|
@ -165,12 +165,12 @@ do
|
|||
s ← get;
|
||||
match s.map.find k with
|
||||
| some ps := do
|
||||
ps ← ps.mmap $ λ (p : Param),
|
||||
ps ← ps.mmap $ fun (p : Param) =>
|
||||
if p.borrow && s.owned.contains p.x.idx then do
|
||||
markModifiedParamMap; pure { borrow := false, .. p }
|
||||
else
|
||||
pure p;
|
||||
modify $ λ s, { map := s.map.insert k ps, .. s }
|
||||
modify $ fun s => { map := s.map.insert k ps, .. s }
|
||||
| none := pure ()
|
||||
|
||||
def getParamInfo (k : Key) : M (Array Param) :=
|
||||
|
|
@ -189,7 +189,7 @@ match s.map.find k with
|
|||
|
||||
/- For each ps[i], if ps[i] is owned, then mark xs[i] as owned. -/
|
||||
def ownArgsUsingParams (xs : Array Arg) (ps : Array Param) : M Unit :=
|
||||
xs.size.mfor $ λ i, do
|
||||
xs.size.mfor $ fun i => do
|
||||
let x := xs.get i;
|
||||
let p := ps.get i;
|
||||
unless p.borrow $ ownArg x
|
||||
|
|
@ -200,7 +200,7 @@ xs.size.mfor $ λ i, do
|
|||
we would have to insert a `dec xs[i]` after `f xs` and consequently
|
||||
"break" the tail call. -/
|
||||
def ownParamsUsingArgs (xs : Array Arg) (ps : Array Param) : M Unit :=
|
||||
xs.size.mfor $ λ i, do
|
||||
xs.size.mfor $ fun i => do
|
||||
let x := xs.get i;
|
||||
let p := ps.get i;
|
||||
match x with
|
||||
|
|
@ -220,7 +220,7 @@ xs.size.mfor $ λ i, do
|
|||
def ownArgsIfParam (xs : Array Arg) : M Unit :=
|
||||
do
|
||||
ctx ← read;
|
||||
xs.mfor $ λ x,
|
||||
xs.mfor $ fun x =>
|
||||
match x with
|
||||
| Arg.var x := when (ctx.paramSet.contains x.idx) $ ownVar x
|
||||
| _ := pure ()
|
||||
|
|
@ -231,7 +231,7 @@ def collectExpr (z : VarId) : Expr → M Unit
|
|||
| (Expr.ctor _ xs) := ownVar z *> ownArgsIfParam xs
|
||||
| (Expr.proj _ x) := mwhen (isOwned z) $ ownVar x
|
||||
| (Expr.fap g xs) := do ps ← getParamInfo (Key.decl g);
|
||||
-- dbgTrace ("collectExpr: " ++ toString g ++ " " ++ toString (formatParams ps)) $ λ _,
|
||||
-- dbgTrace ("collectExpr: " ++ toString g ++ " " ++ toString (formatParams ps)) $ fun _ =>
|
||||
ownVar z *> ownArgsUsingParams xs ps
|
||||
| (Expr.ap x ys) := ownVar z *> ownVar x *> ownArgs ys
|
||||
| (Expr.pap _ xs) := ownVar z *> ownArgs xs
|
||||
|
|
@ -242,17 +242,17 @@ do ctx ← read;
|
|||
match v, b with
|
||||
| (Expr.fap g ys), (FnBody.ret (Arg.var z)) :=
|
||||
when (ctx.currFn == g && x == z) $ do
|
||||
-- dbgTrace ("preserveTailCall " ++ toString b) $ λ _, do
|
||||
-- dbgTrace ("preserveTailCall " ++ toString b) $ fun _ => do
|
||||
ps ← getParamInfo (Key.decl g);
|
||||
ownParamsUsingArgs ys ps
|
||||
| _, _ := pure ()
|
||||
|
||||
def updateParamSet (ctx : BorrowInfCtx) (ps : Array Param) : BorrowInfCtx :=
|
||||
{ paramSet := ps.foldl (λ s p, s.insert p.x.idx) ctx.paramSet, .. ctx }
|
||||
{ paramSet := ps.foldl (fun s p => s.insert p.x.idx) ctx.paramSet, .. ctx }
|
||||
|
||||
partial def collectFnBody : FnBody → M Unit
|
||||
| (FnBody.jdecl j ys v b) := do
|
||||
adaptReader (λ ctx, updateParamSet ctx ys) (collectFnBody v);
|
||||
adaptReader (fun ctx => updateParamSet ctx ys) (collectFnBody v);
|
||||
ctx ← read;
|
||||
updateParamMap (Key.jp ctx.currFn j);
|
||||
collectFnBody b
|
||||
|
|
@ -262,12 +262,12 @@ partial def collectFnBody : FnBody → M Unit
|
|||
ps ← getParamInfo (Key.jp ctx.currFn j);
|
||||
ownArgsUsingParams ys ps; -- for making sure the join point can reuse
|
||||
ownParamsUsingArgs ys ps -- for making sure the tail call is preserved
|
||||
| (FnBody.case _ _ alts) := alts.mfor $ λ alt, collectFnBody alt.body
|
||||
| (FnBody.case _ _ alts) := alts.mfor $ fun alt => collectFnBody alt.body
|
||||
| e := unless (e.isTerminal) $ collectFnBody e.body
|
||||
|
||||
@[specialize] partial def whileModifingOwnedAux (x : M Unit) : Unit → M Unit
|
||||
| _ := do
|
||||
modify $ λ s, { modifiedOwned := false, .. s };
|
||||
modify $ fun s => { modifiedOwned := false, .. s };
|
||||
x;
|
||||
s ← get;
|
||||
if s.modifiedOwned then whileModifingOwnedAux ()
|
||||
|
|
@ -279,17 +279,17 @@ whileModifingOwnedAux x ()
|
|||
|
||||
partial def collectDecl : Decl → M Unit
|
||||
| (Decl.fdecl f ys _ b) :=
|
||||
adaptReader (λ ctx, let ctx := updateParamSet ctx ys; { currFn := f, .. ctx }) $ do
|
||||
modify $ λ s : BorrowInfState, { owned := {}, .. s };
|
||||
adaptReader (fun ctx => let ctx := updateParamSet ctx ys; { currFn := f, .. ctx }) $ do
|
||||
modify $ fun s : BorrowInfState => { owned := {}, .. s };
|
||||
whileModifingOwned (collectFnBody b);
|
||||
updateParamMap (Key.decl f)
|
||||
| _ := pure ()
|
||||
|
||||
@[specialize] partial def whileModifingParamMapAux (x : M Unit) : Unit → M Unit
|
||||
| _ := do
|
||||
modify $ λ s, { modifiedParamMap := false, .. s };
|
||||
modify $ fun s => { modifiedParamMap := false, .. s };
|
||||
s ← get;
|
||||
-- dbgTrace (toString s.map) $ λ _, do
|
||||
-- dbgTrace (toString s.map) $ fun _ => do
|
||||
x;
|
||||
s ← get;
|
||||
if s.modifiedParamMap then whileModifingParamMapAux ()
|
||||
|
|
|
|||
|
|
@ -36,19 +36,19 @@ abbrev N := State Nat
|
|||
|
||||
private def mkFresh : N VarId :=
|
||||
do idx ← get;
|
||||
modify (λ n, n + 1);
|
||||
modify (fun n => n + 1);
|
||||
pure {idx := idx }
|
||||
|
||||
def requiresBoxedVersion (env : Environment) (decl : Decl) : Bool :=
|
||||
let ps := decl.params;
|
||||
ps.size > 0 && (decl.resultType.isScalar || ps.any (λ p, p.ty.isScalar || p.borrow) || isExtern env decl.name)
|
||||
ps.size > 0 && (decl.resultType.isScalar || ps.any (fun p => p.ty.isScalar || p.borrow) || isExtern env decl.name)
|
||||
|
||||
def mkBoxedVersionAux (decl : Decl) : N Decl :=
|
||||
do
|
||||
let ps := decl.params;
|
||||
qs ← ps.mmap (λ _, do x ← mkFresh; pure { Param . x := x, ty := IRType.object, borrow := false });
|
||||
qs ← ps.mmap (fun _ => do x ← mkFresh; pure { Param . x := x, ty := IRType.object, borrow := false });
|
||||
(newVDecls, xs) ← qs.size.mfold
|
||||
(λ i (r : Array FnBody × Array Arg),
|
||||
(fun i (r : Array FnBody × Array Arg) =>
|
||||
let (newVDecls, xs) := r;
|
||||
let p := ps.get i;
|
||||
let q := qs.get i;
|
||||
|
|
@ -74,7 +74,7 @@ def mkBoxedVersion (decl : Decl) : Decl :=
|
|||
|
||||
def addBoxedVersions (env : Environment) (decls : Array Decl) : Array Decl :=
|
||||
let boxedDecls := decls.foldl
|
||||
(λ (newDecls : Array Decl) decl, if requiresBoxedVersion env decl then newDecls.push (mkBoxedVersion decl) else newDecls)
|
||||
(fun (newDecls : Array Decl) decl => if requiresBoxedVersion env decl then newDecls.push (mkBoxedVersion decl) else newDecls)
|
||||
Array.empty;
|
||||
decls ++ boxedDecls
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ else
|
|||
def getScrutineeType (alts : Array Alt) : IRType :=
|
||||
let isScalar :=
|
||||
alts.size > 1 && -- Recall that we encode Unit and PUnit using `object`.
|
||||
alts.all (λ alt, match alt with
|
||||
alts.all (fun alt => match alt with
|
||||
| Alt.ctor c _ := c.isScalar
|
||||
| Alt.default _ := false);
|
||||
match isScalar with
|
||||
|
|
@ -111,7 +111,7 @@ structure BoxingContext :=
|
|||
abbrev M := ReaderT BoxingContext (StateT Index Id)
|
||||
|
||||
def mkFresh : M VarId :=
|
||||
do idx ← getModify (λ n, n + 1);
|
||||
do idx ← getModify (fun n => n + 1);
|
||||
pure { idx := idx }
|
||||
|
||||
def getEnv : M Environment := BoxingContext.env <$> read
|
||||
|
|
@ -135,13 +135,13 @@ do ctx ← read;
|
|||
| none := pure (default _) -- unreachable if well-formed
|
||||
|
||||
@[inline] def withParams {α : Type} (xs : Array Param) (k : M α) : M α :=
|
||||
adaptReader (λ ctx : BoxingContext, { localCtx := ctx.localCtx.addParams xs, .. ctx }) k
|
||||
adaptReader (fun ctx : BoxingContext => { localCtx := ctx.localCtx.addParams xs, .. ctx }) k
|
||||
|
||||
@[inline] def withVDecl {α : Type} (x : VarId) (ty : IRType) (v : Expr) (k : M α) : M α :=
|
||||
adaptReader (λ ctx : BoxingContext, { localCtx := ctx.localCtx.addLocal x ty v, .. ctx }) k
|
||||
adaptReader (fun ctx : BoxingContext => { localCtx := ctx.localCtx.addLocal x ty v, .. ctx }) k
|
||||
|
||||
@[inline] def withJDecl {α : Type} (j : JoinPointId) (xs : Array Param) (v : FnBody) (k : M α) : M α :=
|
||||
adaptReader (λ ctx : BoxingContext, { localCtx := ctx.localCtx.addJP j xs v, .. ctx }) k
|
||||
adaptReader (fun ctx : BoxingContext => { localCtx := ctx.localCtx.addJP j xs v, .. ctx }) k
|
||||
|
||||
/- Auxiliary function used by castVarIfNeeded.
|
||||
It is used when the expected type does not match `xType`.
|
||||
|
|
@ -159,11 +159,11 @@ do xType ← getVarType x;
|
|||
|
||||
@[inline] def castArgIfNeeded (x : Arg) (expected : IRType) (k : Arg → M FnBody) : M FnBody :=
|
||||
match x with
|
||||
| Arg.var x := castVarIfNeeded x expected (λ x, k (Arg.var x))
|
||||
| Arg.var x := castVarIfNeeded x expected (fun x => k (Arg.var x))
|
||||
| _ := k x
|
||||
|
||||
@[specialize] def castArgsIfNeededAux (xs : Array Arg) (typeFromIdx : Nat → IRType) : M (Array Arg × Array FnBody) :=
|
||||
xs.miterate (Array.empty, Array.empty) $ λ i (x : Arg) (r : Array Arg × Array FnBody),
|
||||
xs.miterate (Array.empty, Array.empty) $ fun i (x : Arg) (r : Array Arg × Array FnBody) =>
|
||||
let expected := typeFromIdx i.val;
|
||||
let (xs, bs) := r;
|
||||
match x with
|
||||
|
|
@ -178,12 +178,12 @@ xs.miterate (Array.empty, Array.empty) $ λ i (x : Arg) (r : Array Arg × Array
|
|||
pure (xs.push (Arg.var y), bs.push b)
|
||||
|
||||
@[inline] def castArgsIfNeeded (xs : Array Arg) (ps : Array Param) (k : Array Arg → M FnBody) : M FnBody :=
|
||||
do (ys, bs) ← castArgsIfNeededAux xs (λ i, (ps.get i).ty);
|
||||
do (ys, bs) ← castArgsIfNeededAux xs (fun i => (ps.get i).ty);
|
||||
b ← k ys;
|
||||
pure (reshape bs b)
|
||||
|
||||
@[inline] def boxArgsIfNeeded (xs : Array Arg) (k : Array Arg → M FnBody) : M FnBody :=
|
||||
do (ys, bs) ← castArgsIfNeededAux xs (λ _, IRType.object);
|
||||
do (ys, bs) ← castArgsIfNeededAux xs (fun _ => IRType.object);
|
||||
b ← k ys;
|
||||
pure (reshape bs b)
|
||||
|
||||
|
|
@ -206,20 +206,20 @@ match e with
|
|||
if c.isScalar && ty.isScalar then
|
||||
pure $ FnBody.vdecl x ty (Expr.lit (LitVal.num c.cidx)) b
|
||||
else
|
||||
boxArgsIfNeeded ys $ λ ys, pure $ FnBody.vdecl x ty (Expr.ctor c ys) b
|
||||
boxArgsIfNeeded ys $ fun ys => pure $ FnBody.vdecl x ty (Expr.ctor c ys) b
|
||||
| Expr.reuse w c u ys :=
|
||||
boxArgsIfNeeded ys $ λ ys, pure $ FnBody.vdecl x ty (Expr.reuse w c u ys) b
|
||||
boxArgsIfNeeded ys $ fun ys => pure $ FnBody.vdecl x ty (Expr.reuse w c u ys) b
|
||||
| Expr.fap f ys := do
|
||||
decl ← getDecl f;
|
||||
castArgsIfNeeded ys decl.params $ λ ys,
|
||||
castArgsIfNeeded ys decl.params $ fun ys =>
|
||||
castResultIfNeeded x ty (Expr.fap f ys) decl.resultType b
|
||||
| Expr.pap f ys := do
|
||||
env ← getEnv;
|
||||
decl ← getDecl f;
|
||||
let f := if requiresBoxedVersion env decl then mkBoxedName f else f;
|
||||
boxArgsIfNeeded ys $ λ ys, pure $ FnBody.vdecl x ty (Expr.pap f ys) b
|
||||
boxArgsIfNeeded ys $ fun ys => pure $ FnBody.vdecl x ty (Expr.pap f ys) b
|
||||
| Expr.ap f ys :=
|
||||
boxArgsIfNeeded ys $ λ ys,
|
||||
boxArgsIfNeeded ys $ fun ys =>
|
||||
unboxResultIfNeeded x ty (Expr.ap f ys) b
|
||||
| other :=
|
||||
pure $ FnBody.vdecl x ty e b
|
||||
|
|
@ -234,31 +234,31 @@ partial def visitFnBody : FnBody → M FnBody
|
|||
pure $ FnBody.jdecl j xs v b
|
||||
| (FnBody.uset x i y b) := do
|
||||
b ← visitFnBody b;
|
||||
castVarIfNeeded y IRType.usize $ λ y,
|
||||
castVarIfNeeded y IRType.usize $ fun y =>
|
||||
pure $ FnBody.uset x i y b
|
||||
| (FnBody.sset x i o y ty b) := do
|
||||
b ← visitFnBody b;
|
||||
castVarIfNeeded y ty $ λ y,
|
||||
castVarIfNeeded y ty $ fun y =>
|
||||
pure $ FnBody.sset x i o y ty b
|
||||
| (FnBody.mdata d b) :=
|
||||
FnBody.mdata d <$> visitFnBody b
|
||||
| (FnBody.case tid x alts) := do
|
||||
let expected := getScrutineeType alts;
|
||||
alts ← alts.mmap $ λ alt, alt.mmodifyBody visitFnBody;
|
||||
castVarIfNeeded x expected $ λ x,
|
||||
alts ← alts.mmap $ fun alt => alt.mmodifyBody visitFnBody;
|
||||
castVarIfNeeded x expected $ fun x =>
|
||||
pure $ FnBody.case tid x alts
|
||||
| (FnBody.ret x) := do
|
||||
expected ← getResultType;
|
||||
castArgIfNeeded x expected (λ x, pure $ FnBody.ret x)
|
||||
castArgIfNeeded x expected (fun x => pure $ FnBody.ret x)
|
||||
| (FnBody.jmp j ys) := do
|
||||
ps ← getJPParams j;
|
||||
castArgsIfNeeded ys ps (λ ys, pure $ FnBody.jmp j ys)
|
||||
castArgsIfNeeded ys ps (fun ys => pure $ FnBody.jmp j ys)
|
||||
| other :=
|
||||
pure other
|
||||
|
||||
def run (env : Environment) (decls : Array Decl) : Array Decl :=
|
||||
let ctx : BoxingContext := { decls := decls, env := env };
|
||||
let decls := decls.map (λ decl, match decl with
|
||||
let decls := decls.map (fun decl => match decl with
|
||||
| Decl.fdecl f xs t b :=
|
||||
let nextIdx := decl.maxIndex + 1;
|
||||
let b := (withParams xs (visitFnBody b) { resultType := t, .. ctx }).run' nextIdx;
|
||||
|
|
|
|||
|
|
@ -76,34 +76,34 @@ def checkExpr (ty : IRType) : Expr → M Unit
|
|||
| (Expr.ctor c ys) := when c.isRef (checkObjType ty) *> checkArgs ys
|
||||
| (Expr.reset _ x) := checkObjVar x *> checkObjType ty
|
||||
| (Expr.reuse x i u ys) := checkObjVar x *> checkArgs ys *> checkObjType ty
|
||||
| (Expr.box xty x) := checkObjType ty *> checkScalarVar x *> checkVarType x (λ t, t == xty)
|
||||
| (Expr.box xty x) := checkObjType ty *> checkScalarVar x *> checkVarType x (fun t => t == xty)
|
||||
| (Expr.unbox x) := checkScalarType ty *> checkObjVar x
|
||||
| (Expr.proj _ x) := checkObjVar x *> checkObjType ty
|
||||
| (Expr.uproj _ x) := checkObjVar x *> checkType ty (λ t, t == IRType.usize)
|
||||
| (Expr.uproj _ x) := checkObjVar x *> checkType ty (fun t => t == IRType.usize)
|
||||
| (Expr.sproj _ _ x) := checkObjVar x *> checkScalarType ty
|
||||
| (Expr.isShared x) := checkObjVar x *> checkType ty (λ t, t == IRType.uint8)
|
||||
| (Expr.isTaggedPtr x) := checkObjVar x *> checkType ty (λ t, t == IRType.uint8)
|
||||
| (Expr.isShared x) := checkObjVar x *> checkType ty (fun t => t == IRType.uint8)
|
||||
| (Expr.isTaggedPtr x) := checkObjVar x *> checkType ty (fun t => t == IRType.uint8)
|
||||
| (Expr.lit (LitVal.str _)) := checkObjType ty
|
||||
| (Expr.lit _) := pure ()
|
||||
|
||||
@[inline] def withParams (ps : Array Param) (k : M Unit) : M Unit :=
|
||||
do ctx ← read;
|
||||
localCtx ← ps.mfoldl (λ (ctx : LocalContext) p, do
|
||||
localCtx ← ps.mfoldl (fun (ctx : LocalContext) p => do
|
||||
when (ctx.contains p.x.idx) $ throw ("invalid parameter declaration, shadowing is not allowed");
|
||||
pure $ ctx.addParam p) ctx.localCtx;
|
||||
adaptReader (λ _, { localCtx := localCtx, .. ctx }) k
|
||||
adaptReader (fun _ => { localCtx := localCtx, .. ctx }) k
|
||||
|
||||
partial def checkFnBody : FnBody → M Unit
|
||||
| (FnBody.vdecl x t v b) := do
|
||||
checkExpr t v;
|
||||
ctx ← read;
|
||||
when (ctx.localCtx.contains x.idx) $ throw ("invalid variable declaration, shadowing is not allowed");
|
||||
adaptReader (λ ctx : Context, { localCtx := ctx.localCtx.addLocal x t v, .. ctx }) (checkFnBody b)
|
||||
adaptReader (fun (ctx : Context) => { localCtx := ctx.localCtx.addLocal x t v, .. ctx }) (checkFnBody b)
|
||||
| (FnBody.jdecl j ys v b) := do
|
||||
withParams ys (checkFnBody v);
|
||||
ctx ← read;
|
||||
when (ctx.localCtx.contains j.idx) $ throw ("invalid join point declaration, shadowing is not allowed");
|
||||
adaptReader (λ ctx : Context, { localCtx := ctx.localCtx.addJP j ys v, .. ctx }) (checkFnBody b)
|
||||
adaptReader (fun (ctx : Context) => { localCtx := ctx.localCtx.addJP j ys v, .. ctx }) (checkFnBody b)
|
||||
| (FnBody.set x _ y b) := checkVar x *> checkArg y *> checkFnBody b
|
||||
| (FnBody.uset x _ y b) := checkVar x *> checkVar y *> checkFnBody b
|
||||
| (FnBody.sset x _ _ y _ b) := checkVar x *> checkVar y *> checkFnBody b
|
||||
|
|
@ -114,7 +114,7 @@ partial def checkFnBody : FnBody → M Unit
|
|||
| (FnBody.mdata _ b) := checkFnBody b
|
||||
| (FnBody.jmp j ys) := checkJP j *> checkArgs ys
|
||||
| (FnBody.ret x) := checkArg x
|
||||
| (FnBody.case _ x alts) := checkVar x *> alts.mfor (λ alt, checkFnBody alt.body)
|
||||
| (FnBody.case _ x alts) := checkVar x *> alts.mfor (fun alt => checkFnBody alt.body)
|
||||
| (FnBody.unreachable) := pure ()
|
||||
|
||||
def checkDecl : Decl → M Unit
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ inductive LogEntry
|
|||
|
||||
namespace LogEntry
|
||||
protected def fmt : LogEntry → Format
|
||||
| (step cls decls) := Format.bracket "[" (format cls) "]" ++ decls.foldl (λ fmt decl, fmt ++ Format.line ++ format decl) Format.nil
|
||||
| (step cls decls) := Format.bracket "[" (format cls) "]" ++ decls.foldl (fun fmt decl => fmt ++ Format.line ++ format decl) Format.nil
|
||||
| (message msg) := msg
|
||||
|
||||
instance : HasFormat LogEntry := ⟨LogEntry.fmt⟩
|
||||
|
|
@ -27,7 +27,7 @@ end LogEntry
|
|||
abbrev Log := Array LogEntry
|
||||
|
||||
def Log.format (log : Log) : Format :=
|
||||
log.foldl (λ fmt entry, fmt ++ Format.line ++ format entry) Format.nil
|
||||
log.foldl (fun fmt entry => fmt ++ Format.line ++ format entry) Format.nil
|
||||
|
||||
@[export lean.ir.log_to_string_core]
|
||||
def Log.toString (log : Log) : String :=
|
||||
|
|
@ -39,7 +39,7 @@ structure CompilerState :=
|
|||
abbrev CompilerM := ReaderT Options (EState String CompilerState)
|
||||
|
||||
def log (entry : LogEntry) : CompilerM Unit :=
|
||||
modify $ λ s, { log := s.log.push entry, .. s }
|
||||
modify $ fun s => { log := s.log.push entry, .. s }
|
||||
|
||||
def tracePrefixOptionName := `trace.compiler.ir
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ logMessageIfAux (tracePrefixOptionName ++ cls) a
|
|||
logMessageIfAux tracePrefixOptionName a
|
||||
|
||||
@[inline] def modifyEnv (f : Environment → Environment) : CompilerM Unit :=
|
||||
modify $ λ s, { env := f s.env, .. s }
|
||||
modify $ fun s => { env := f s.env, .. s }
|
||||
|
||||
abbrev DeclMap := SMap Name Decl Name.quickLt
|
||||
|
||||
|
|
@ -75,16 +75,16 @@ abbrev DeclMap := SMap Name Decl Name.quickLt
|
|||
private def mkEntryArray (decls : List Decl) : Array Decl :=
|
||||
/- Remove duplicates by adding decls into a map -/
|
||||
let map : HashMap Name Decl := {};
|
||||
let map := decls.foldl (λ (map : HashMap Name Decl) decl, map.insert decl.name decl) map;
|
||||
map.fold (λ a k v, a.push v) Array.empty
|
||||
let map := decls.foldl (fun (map : HashMap Name Decl) decl => map.insert decl.name decl) map;
|
||||
map.fold (fun a k v => a.push v) Array.empty
|
||||
|
||||
def mkDeclMapExtension : IO (SimplePersistentEnvExtension Decl DeclMap) :=
|
||||
registerSimplePersistentEnvExtension {
|
||||
name := `IRDecls,
|
||||
addImportedFn := λ as,
|
||||
let m : DeclMap := mkStateFromImportedEntries (λ s (d : Decl), s.insert d.name d) {} as;
|
||||
addImportedFn := fun as =>
|
||||
let m : DeclMap := mkStateFromImportedEntries (fun s (d : Decl) => s.insert d.name d) {} as;
|
||||
m.switch,
|
||||
addEntryFn := λ s d, s.insert d.name d,
|
||||
addEntryFn := fun s d => s.insert d.name d,
|
||||
toArrayFn := mkEntryArray
|
||||
}
|
||||
|
||||
|
|
@ -117,13 +117,13 @@ def getEnv : CompilerM Environment :=
|
|||
do s ← get; pure s.env
|
||||
|
||||
def addDecl (decl : Decl) : CompilerM Unit :=
|
||||
modifyEnv (λ env, declMapExt.addEntry env decl)
|
||||
modifyEnv (fun env => declMapExt.addEntry env decl)
|
||||
|
||||
def addDecls (decls : Array Decl) : CompilerM Unit :=
|
||||
decls.mfor addDecl
|
||||
|
||||
def findEnvDecl' (env : Environment) (n : Name) (decls : Array Decl) : Option Decl :=
|
||||
match decls.find (λ decl, if decl.name == n then some decl else none) with
|
||||
match decls.find (fun decl => if decl.name == n then some decl else none) with
|
||||
| some decl := some decl
|
||||
| none := (declMapExt.getState env).find n
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ def findDecl' (n : Name) (decls : Array Decl) : CompilerM (Option Decl) :=
|
|||
do s ← get; pure $ findEnvDecl' s.env n decls
|
||||
|
||||
def containsDecl' (n : Name) (decls : Array Decl) : CompilerM Bool :=
|
||||
if decls.any (λ decl, decl.name == n) then pure true
|
||||
if decls.any (fun decl => decl.name == n) then pure true
|
||||
else do
|
||||
s ← get;
|
||||
pure $ (declMapExt.getState s.env).contains n
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ partial def FnBody.elimDead : FnBody → FnBody
|
|||
let bs := modifyJPs bs FnBody.elimDead;
|
||||
let term := match term with
|
||||
| FnBody.case tid x alts :=
|
||||
let alts := alts.map $ λ alt, alt.modifyBody FnBody.elimDead;
|
||||
let alts := alts.map $ fun alt => alt.modifyBody FnBody.elimDead;
|
||||
FnBody.case tid x alts
|
||||
| other := other;
|
||||
reshapeWithoutDead bs term
|
||||
|
|
|
|||
|
|
@ -41,13 +41,13 @@ do env ← getEnv;
|
|||
| none := throw ("unknown declaration '" ++ toString n ++ "'")
|
||||
|
||||
@[inline] def emit {α : Type} [HasToString α] (a : α) : M Unit :=
|
||||
modify (λ out, out ++ toString a)
|
||||
modify (fun out => out ++ toString a)
|
||||
|
||||
@[inline] def emitLn {α : Type} [HasToString α] (a : α) : M Unit :=
|
||||
emit a *> emit "\n"
|
||||
|
||||
def emitLns {α : Type} [HasToString α] (as : List α) : M Unit :=
|
||||
as.mfor $ λ a, emitLn a
|
||||
as.mfor $ fun a => emitLn a
|
||||
|
||||
def argToCppString (x : Arg) : String :=
|
||||
match x with
|
||||
|
|
@ -132,7 +132,7 @@ when (ps.isEmpty && addExternForConsts) (emit "extern ");
|
|||
emit (toCppType decl.resultType ++ " " ++ cppBaseName);
|
||||
unless (ps.isEmpty) $ do {
|
||||
emit "(";
|
||||
ps.size.mfor $ λ i, do {
|
||||
ps.size.mfor $ fun i => do {
|
||||
when (i > 0) (emit ", ");
|
||||
emit (toCppType (ps.get i).ty)
|
||||
};
|
||||
|
|
@ -165,10 +165,10 @@ def emitFnDecls : M Unit :=
|
|||
do
|
||||
env ← getEnv;
|
||||
let decls := getDecls env;
|
||||
let modDecls : NameSet := decls.foldl (λ s d, s.insert d.name) {};
|
||||
let usedDecls : NameSet := decls.foldl (λ s d, collectUsedDecls env d (s.insert d.name)) {};
|
||||
let modDecls : NameSet := decls.foldl (fun s d => s.insert d.name) {};
|
||||
let usedDecls : NameSet := decls.foldl (fun s d => collectUsedDecls env d (s.insert d.name)) {};
|
||||
let usedDecls := usedDecls.toList;
|
||||
usedDecls.mfor $ λ n, do
|
||||
usedDecls.mfor $ fun n => do
|
||||
decl ← getDecl n;
|
||||
match getExternNameFor env `cpp decl.name with
|
||||
| some cppName := emitExternDeclAux decl cppName
|
||||
|
|
@ -222,7 +222,7 @@ match d with
|
|||
def hasMainFn : M Bool :=
|
||||
do env ← getEnv;
|
||||
let decls := getDecls env;
|
||||
pure $ decls.any (λ d, d.name == `main)
|
||||
pure $ decls.any (fun d => d.name == `main)
|
||||
|
||||
def emitMainFnIfNeeded : M Unit :=
|
||||
mwhen hasMainFn emitMainFn
|
||||
|
|
@ -234,7 +234,7 @@ modName ← getModName;
|
|||
emitLn "// Lean compiler output";
|
||||
emitLn ("// Module: " ++ toString modName);
|
||||
emit "// Imports:";
|
||||
env.imports.mfor $ λ m, emit (" " ++ toString m);
|
||||
env.imports.mfor $ fun m => emit (" " ++ toString m);
|
||||
emitLn "";
|
||||
emitLn "#include \"runtime/object.h\"";
|
||||
emitLn "#include \"runtime/apply.h\"";
|
||||
|
|
@ -271,7 +271,7 @@ def declareVar (x : VarId) (t : IRType) : M Unit :=
|
|||
do emit (toCppType t); emit " "; emit x; emit "; "
|
||||
|
||||
def declareParams (ps : Array Param) : M Unit :=
|
||||
ps.mfor $ λ p, declareVar p.x p.ty
|
||||
ps.mfor $ fun p => declareVar p.x p.ty
|
||||
|
||||
partial def declareVars : FnBody → Bool → M Bool
|
||||
| e@(FnBody.vdecl x t _ b) d := do
|
||||
|
|
@ -310,7 +310,7 @@ match isIf alts with
|
|||
| _ := do
|
||||
emit "switch ("; emitTag x; emitLn ") {";
|
||||
let alts := ensureHasDefault alts;
|
||||
alts.mfor $ λ alt, match alt with
|
||||
alts.mfor $ fun alt => match alt with
|
||||
| Alt.ctor c b := emit "case " *> emit c.cidx *> emitLn ":" *> emitBody b
|
||||
| Alt.default b := emitLn "default: " *> emitBody b;
|
||||
emitLn "}"
|
||||
|
|
@ -355,7 +355,7 @@ def emitJmp (j : JoinPointId) (xs : Array Arg) : M Unit :=
|
|||
do
|
||||
ps ← getJPParams j;
|
||||
unless (xs.size == ps.size) (throw "invalid goto");
|
||||
xs.size.mfor $ λ i, do {
|
||||
xs.size.mfor $ fun i => do {
|
||||
let p := ps.get i;
|
||||
let x := xs.get i;
|
||||
emit p.x; emit " = "; emitArg x; emitLn ";"
|
||||
|
|
@ -366,7 +366,7 @@ def emitLhs (z : VarId) : M Unit :=
|
|||
do emit z; emit " = "
|
||||
|
||||
def emitArgs (ys : Array Arg) : M Unit :=
|
||||
ys.size.mfor $ λ i, do
|
||||
ys.size.mfor $ fun i => do
|
||||
when (i > 0) (emit ", ");
|
||||
emitArg (ys.get i)
|
||||
|
||||
|
|
@ -381,7 +381,7 @@ emit "lean::alloc_cnstr("; emit c.cidx; emit ", "; emit c.size; emit ", ";
|
|||
emitCtorScalarSize c.usize c.ssize; emitLn ");"
|
||||
|
||||
def emitCtorSetArgs (z : VarId) (ys : Array Arg) : M Unit :=
|
||||
ys.size.mfor $ λ i, do
|
||||
ys.size.mfor $ fun i => do
|
||||
emit "lean::cnstr_set("; emit z; emit ", "; emit i; emit ", "; emitArg (ys.get i); emitLn ");"
|
||||
|
||||
def emitCtor (z : VarId) (c : CtorInfo) (ys : Array Arg) : M Unit :=
|
||||
|
|
@ -395,7 +395,7 @@ else do
|
|||
def emitReset (z : VarId) (n : Nat) (x : VarId) : M Unit :=
|
||||
do
|
||||
emit "if (lean::is_exclusive("; emit x; emitLn ")) {";
|
||||
n.mfor $ λ i, do {
|
||||
n.mfor $ fun i => do {
|
||||
emit " lean::cnstr_release("; emit x; emit ", "; emit i; emitLn ");"
|
||||
};
|
||||
emit " "; emitLhs z; emit x; emitLn ";";
|
||||
|
|
@ -442,7 +442,7 @@ do
|
|||
decl ← getDecl f;
|
||||
let arity := decl.params.size;
|
||||
emitLhs z; emit "lean::alloc_closure(reinterpret_cast<void*>("; emitCppName f; emit "), "; emit arity; emit ", "; emit ys.size; emitLn ");";
|
||||
ys.size.mfor $ λ i, do {
|
||||
ys.size.mfor $ fun i => do {
|
||||
let y := ys.get i;
|
||||
emit "lean::closure_set("; emit z; emit ", "; emit i; emit ", "; emitArg y; emitLn ");"
|
||||
}
|
||||
|
|
@ -488,7 +488,7 @@ String.singleton c.digitChar
|
|||
def quoteString (s : String) : String :=
|
||||
let q := "\"";
|
||||
let q := s.foldl
|
||||
(λ q c, q ++
|
||||
(fun q c => q ++
|
||||
if c == '\n' then "\\n"
|
||||
else if c == '\n' then "\\t"
|
||||
else if c == '\\' then "\\\\"
|
||||
|
|
@ -560,9 +560,9 @@ That is, we have
|
|||
-/
|
||||
def overwriteParam (ps : Array Param) (ys : Array Arg) : Bool :=
|
||||
let n := ps.size;
|
||||
n.any $ λ i,
|
||||
n.any $ fun i =>
|
||||
let p := ps.get i;
|
||||
(i+1, n).anyI $ λ j, paramEqArg p (ys.get j)
|
||||
(i+1, n).anyI $ fun j => paramEqArg p (ys.get j)
|
||||
|
||||
def emitTailCall (v : Expr) : M Unit :=
|
||||
match v with
|
||||
|
|
@ -572,21 +572,21 @@ match v with
|
|||
unless (ps.size == ys.size) (throw "invalid tail call");
|
||||
if overwriteParam ps ys then do {
|
||||
emitLn "{";
|
||||
ps.size.mfor $ λ i, do {
|
||||
ps.size.mfor $ fun i => do {
|
||||
let p := ps.get i;
|
||||
let y := ys.get i;
|
||||
unless (paramEqArg p y) $ do {
|
||||
emit (toCppType p.ty); emit " _tmp_"; emit i; emit " = "; emitArg y; emitLn ";"
|
||||
}
|
||||
};
|
||||
ps.size.mfor $ λ i, do {
|
||||
ps.size.mfor $ fun i => do {
|
||||
let p := ps.get i;
|
||||
let y := ys.get i;
|
||||
unless (paramEqArg p y) (do emit p.x; emit " = _tmp_"; emit i; emitLn ";")
|
||||
};
|
||||
emitLn "}"
|
||||
} else do {
|
||||
ys.size.mfor $ λ i, do {
|
||||
ys.size.mfor $ fun i => do {
|
||||
let p := ps.get i;
|
||||
let y := ys.get i;
|
||||
unless (paramEqArg p y) (do emit p.x; emit " = "; emitArg y; emitLn ";")
|
||||
|
|
@ -629,7 +629,7 @@ def emitDeclAux (d : Decl) : M Unit :=
|
|||
do
|
||||
env ← getEnv;
|
||||
let (vMap, jpMap) := mkVarJPMaps d;
|
||||
adaptReader (λ ctx : Context, { varMap := vMap, jpMap := jpMap, .. ctx }) $ do
|
||||
adaptReader (fun ctx : Context => { varMap := vMap, jpMap := jpMap, .. ctx }) $ do
|
||||
unless (hasInitAttr env d.name) $
|
||||
match d with
|
||||
| Decl.fdecl f xs t b := do
|
||||
|
|
@ -639,7 +639,7 @@ unless (hasInitAttr env d.name) $
|
|||
if xs.size > 0 then do {
|
||||
emit baseName;
|
||||
emit "(";
|
||||
xs.size.mfor $ λ i, do {
|
||||
xs.size.mfor $ fun i => do {
|
||||
when (i > 0) (emit ", ");
|
||||
let x := xs.get i;
|
||||
emit (toCppType x.ty); emit " "; emit(x.x)
|
||||
|
|
@ -650,7 +650,7 @@ unless (hasInitAttr env d.name) $
|
|||
};
|
||||
emitLn " {";
|
||||
emitLn "_start:";
|
||||
adaptReader (λ ctx : Context, { mainFn := f, mainParams := xs, .. ctx }) (emitFnBody b);
|
||||
adaptReader (fun ctx : Context => { mainFn := f, mainParams := xs, .. ctx }) (emitFnBody b);
|
||||
emitLn "}";
|
||||
closeNamespacesFor f
|
||||
| _ := pure ()
|
||||
|
|
@ -659,7 +659,7 @@ def emitDecl (d : Decl) : M Unit :=
|
|||
let d := d.normalizeIds;
|
||||
catch
|
||||
(emitDeclAux d)
|
||||
(λ err, throw (err ++ "\ncompiling:\n" ++ toString d))
|
||||
(fun err => throw (err ++ "\ncompiling:\n" ++ toString d))
|
||||
|
||||
def emitFns : M Unit :=
|
||||
do
|
||||
|
|
@ -717,7 +717,7 @@ def emitInitFn : M Unit :=
|
|||
do
|
||||
env ← getEnv;
|
||||
modName ← getModName;
|
||||
env.imports.mfor $ λ m, emitLn ("obj* initialize_" ++ m.mangle "" ++ "(obj*);");
|
||||
env.imports.mfor $ fun m => emitLn ("obj* initialize_" ++ m.mangle "" ++ "(obj*);");
|
||||
emitLns [
|
||||
"static bool _G_initialized = false;",
|
||||
"obj* initialize_" ++ modName.mangle "" ++ "(obj* w) {",
|
||||
|
|
@ -725,7 +725,7 @@ emitLns [
|
|||
"_G_initialized = true;",
|
||||
"if (io_result_is_error(w)) return w;"
|
||||
];
|
||||
env.imports.mfor $ λ m, emitLns [
|
||||
env.imports.mfor $ fun m => emitLns [
|
||||
"w = initialize_" ++ m.mangle "" ++ "(w);",
|
||||
"if (io_result_is_error(w)) return w;"
|
||||
];
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ partial def visitFnBody : FnBody → M Bool
|
|||
if s.contains f then
|
||||
visitFnBody b
|
||||
else do
|
||||
modify (λ s, s.insert f);
|
||||
modify (fun s => s.insert f);
|
||||
env ← read;
|
||||
match findEnvDecl env f with
|
||||
| some (Decl.fdecl _ _ _ fbody) := visitFnBody fbody <||> visitFnBody b
|
||||
|
|
@ -44,7 +44,7 @@ partial def visitFnBody : FnBody → M Bool
|
|||
| Expr.pap f _ := checkFn f
|
||||
| other := visitFnBody b
|
||||
| (FnBody.jdecl _ _ v b) := visitFnBody v <||> visitFnBody b
|
||||
| (FnBody.case _ _ alts) := alts.anyM $ λ alt, visitFnBody alt.body
|
||||
| (FnBody.case _ _ alts) := alts.anyM $ fun alt => visitFnBody alt.body
|
||||
| e :=
|
||||
if e.isTerminal then pure false
|
||||
else visitFnBody e.body
|
||||
|
|
@ -61,7 +61,7 @@ namespace CollectUsedDecls
|
|||
abbrev M := ReaderT Environment (State NameSet)
|
||||
|
||||
@[inline] def collect (f : FunId) : M Unit :=
|
||||
modify (λ s, s.insert f)
|
||||
modify (fun s => s.insert f)
|
||||
|
||||
partial def collectFnBody : FnBody → M Unit
|
||||
| (FnBody.vdecl _ _ v b) :=
|
||||
|
|
@ -70,7 +70,7 @@ partial def collectFnBody : FnBody → M Unit
|
|||
| Expr.pap f _ := collect f *> collectFnBody b
|
||||
| other := collectFnBody b
|
||||
| (FnBody.jdecl _ _ v b) := collectFnBody v *> collectFnBody b
|
||||
| (FnBody.case _ _ alts) := alts.mfor $ λ alt, collectFnBody alt.body
|
||||
| (FnBody.case _ _ alts) := alts.mfor $ fun alt => collectFnBody alt.body
|
||||
| e := unless e.isTerminal $ collectFnBody e.body
|
||||
|
||||
def collectInitDecl (fn : Name) : M Unit :=
|
||||
|
|
@ -96,7 +96,7 @@ abbrev Collector := (VarTypeMap × JPParamsMap) → (VarTypeMap × JPParamsMap)
|
|||
@[inline] def collectVar (x : VarId) (t : IRType) : Collector
|
||||
| (vs, js) := (vs.insert x t, js)
|
||||
def collectParams (ps : Array Param) : Collector :=
|
||||
λ s, ps.foldl (λ s p, collectVar p.x p.ty s) s
|
||||
fun s => ps.foldl (fun s p => collectVar p.x p.ty s) s
|
||||
@[inline] def collectJP (j : JoinPointId) (xs : Array Param) : Collector
|
||||
| (vs, js) := (vs, js.insert j xs)
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ def collectParams (ps : Array Param) : Collector :=
|
|||
partial def collectFnBody : FnBody → Collector
|
||||
| (FnBody.vdecl x t _ b) := collectVar x t ∘ collectFnBody b
|
||||
| (FnBody.jdecl j xs v b) := collectJP j xs ∘ collectParams xs ∘ collectFnBody v ∘ collectFnBody b
|
||||
| (FnBody.case _ _ alts) := λ s, alts.foldl (λ s alt, collectFnBody alt.body s) s
|
||||
| (FnBody.case _ _ alts) := fun s => alts.foldl (fun s alt => collectFnBody alt.body s) s
|
||||
| e := if e.isTerminal then id else collectFnBody e.body
|
||||
|
||||
def collectDecl : Decl → Collector
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ abbrev ProjMap := HashMap VarId Expr
|
|||
namespace CollectProjMap
|
||||
abbrev Collector := ProjMap → ProjMap
|
||||
@[inline] def collectVDecl (x : VarId) (v : Expr) : Collector :=
|
||||
λ m, match v with
|
||||
fun m => match v with
|
||||
| Expr.proj _ _ := m.insert x v
|
||||
| Expr.sproj _ _ _ := m.insert x v
|
||||
| Expr.uproj _ _ := m.insert x v
|
||||
|
|
@ -27,7 +27,7 @@ abbrev Collector := ProjMap → ProjMap
|
|||
partial def collectFnBody : FnBody → Collector
|
||||
| (FnBody.vdecl x _ v b) := collectVDecl x v ∘ collectFnBody b
|
||||
| (FnBody.jdecl _ _ v b) := collectFnBody v ∘ collectFnBody b
|
||||
| (FnBody.case _ _ alts) := λ s, alts.foldl (λ s alt, collectFnBody alt.body s) s
|
||||
| (FnBody.case _ _ alts) := fun s => alts.foldl (fun s alt => collectFnBody alt.body s) s
|
||||
| e := if e.isTerminal then id else collectFnBody e.body
|
||||
end CollectProjMap
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ partial def consumed (x : VarId) : FnBody → Bool
|
|||
| Expr.reuse y _ _ _ := x == y || consumed b
|
||||
| _ := consumed b
|
||||
| (FnBody.dec y _ _ b) := x == y || consumed b
|
||||
| (FnBody.case _ _ alts) := alts.all $ λ alt, consumed alt.body
|
||||
| (FnBody.case _ _ alts) := alts.all $ fun alt => consumed alt.body
|
||||
| e := !e.isTerminal && consumed e.body
|
||||
|
||||
abbrev Mask := Array (Option VarId)
|
||||
|
|
@ -105,7 +105,7 @@ partial def reuseToCtor (x : VarId) : FnBody → FnBody
|
|||
| _ :=
|
||||
FnBody.vdecl z t v (reuseToCtor b)
|
||||
| (FnBody.case tid y alts) :=
|
||||
let alts := alts.map $ λ alt, alt.modifyBody reuseToCtor;
|
||||
let alts := alts.map $ fun alt => alt.modifyBody reuseToCtor;
|
||||
FnBody.case tid y alts
|
||||
| e :=
|
||||
if e.isTerminal then e
|
||||
|
|
@ -130,18 +130,18 @@ def mkSlowPath (x y : VarId) (mask : Mask) (b : FnBody) : FnBody :=
|
|||
let b := reuseToCtor x b;
|
||||
let b := FnBody.dec y 1 true b;
|
||||
mask.foldl
|
||||
(λ b m, match m with
|
||||
(fun b m => match m with
|
||||
| some z := FnBody.inc z 1 true b
|
||||
| none := b)
|
||||
b
|
||||
|
||||
abbrev M := ReaderT Context (State Nat)
|
||||
def mkFresh : M VarId :=
|
||||
do idx ← get; modify (λ n, n + 1); pure { idx := idx }
|
||||
do idx ← get; modify (fun n => n + 1); pure { idx := idx }
|
||||
|
||||
def releaseUnreadFields (y : VarId) (mask : Mask) (b : FnBody) : M FnBody :=
|
||||
mask.size.mfold
|
||||
(λ i b,
|
||||
(fun i b =>
|
||||
match mask.get i with
|
||||
| some _ := pure b -- code took ownership of this field
|
||||
| none := do
|
||||
|
|
@ -151,7 +151,7 @@ mask.size.mfold
|
|||
|
||||
def setFields (y : VarId) (zs : Array Arg) (b : FnBody) : FnBody :=
|
||||
zs.size.fold
|
||||
(λ i b, FnBody.set y i (zs.get i) b)
|
||||
(fun i b => FnBody.set y i (zs.get i) b)
|
||||
b
|
||||
|
||||
/- Given `set x[i] := y`, return true iff `y := proj[i] x` -/
|
||||
|
|
@ -187,7 +187,7 @@ partial def removeSelfSet (ctx : Context) : FnBody → FnBody
|
|||
if isSelfSSet ctx x n i y then removeSelfSet b
|
||||
else FnBody.sset x n i y t (removeSelfSet b)
|
||||
| (FnBody.case tid y alts) :=
|
||||
let alts := alts.map $ λ alt, alt.modifyBody removeSelfSet;
|
||||
let alts := alts.map $ fun alt => alt.modifyBody removeSelfSet;
|
||||
FnBody.case tid y alts
|
||||
| e :=
|
||||
if e.isTerminal then e
|
||||
|
|
@ -210,7 +210,7 @@ partial def reuseToSet (ctx : Context) (x y : VarId) : FnBody → FnBody
|
|||
else FnBody.vdecl z t v (reuseToSet b)
|
||||
| _ := FnBody.vdecl z t v (reuseToSet b)
|
||||
| (FnBody.case tid y alts) :=
|
||||
let alts := alts.map $ λ alt, alt.modifyBody reuseToSet;
|
||||
let alts := alts.map $ fun alt => alt.modifyBody reuseToSet;
|
||||
FnBody.case tid y alts
|
||||
| e :=
|
||||
if e.isTerminal then e
|
||||
|
|
@ -268,7 +268,7 @@ partial def searchAndExpand : FnBody → Array FnBody → M FnBody
|
|||
v ← searchAndExpand v Array.empty;
|
||||
searchAndExpand b (push bs (FnBody.jdecl j xs v FnBody.nil))
|
||||
| (FnBody.case tid x alts) bs := do
|
||||
alts ← alts.mmap $ λ alt, alt.mmodifyBody $ λ b, searchAndExpand b Array.empty;
|
||||
alts ← alts.mmap $ fun alt => alt.mmodifyBody $ fun b => searchAndExpand b Array.empty;
|
||||
pure $ reshape bs (FnBody.case tid x alts)
|
||||
| b bs :=
|
||||
if b.isTerminal then pure $ reshape bs b
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ private def formatArg : Arg → Format
|
|||
instance argHasFormat : HasFormat Arg := ⟨formatArg⟩
|
||||
|
||||
private def formatArray {α : Type} [HasFormat α] (args : Array α) : Format :=
|
||||
args.foldl (λ r a, r ++ " " ++ format a) Format.nil
|
||||
args.foldl (fun r a => r ++ " " ++ format a) Format.nil
|
||||
|
||||
private def formatLitVal : LitVal → Format
|
||||
| (LitVal.num v) := format v
|
||||
|
|
@ -50,7 +50,7 @@ private def formatExpr : Expr → Format
|
|||
| (Expr.isTaggedPtr x) := "isTaggedPtr " ++ format x
|
||||
|
||||
instance exprHasFormat : HasFormat Expr := ⟨formatExpr⟩
|
||||
instance exprHasToString : HasToString Expr := ⟨λ e, Format.pretty (format e)⟩
|
||||
instance exprHasToString : HasToString Expr := ⟨fun e => Format.pretty (format e)⟩
|
||||
|
||||
private def formatIRType : IRType → Format
|
||||
| IRType.float := "float"
|
||||
|
|
@ -88,13 +88,13 @@ partial def formatFnBody (indent : Nat := 2) : FnBody → Format
|
|||
| (FnBody.dec x n c b) := "dec" ++ (if n != 1 then Format.sbracket (format n) else "") ++ " " ++ format x ++ ";" ++ Format.line ++ formatFnBody b
|
||||
| (FnBody.del x b) := "del " ++ format x ++ ";" ++ Format.line ++ formatFnBody b
|
||||
| (FnBody.mdata d b) := "mdata " ++ format d ++ ";" ++ Format.line ++ formatFnBody b
|
||||
| (FnBody.case tid x cs) := "case " ++ format x ++ " of" ++ cs.foldl (λ r c, r ++ Format.line ++ formatAlt formatFnBody indent c) Format.nil
|
||||
| (FnBody.case tid x cs) := "case " ++ format x ++ " of" ++ cs.foldl (fun r c => r ++ Format.line ++ formatAlt formatFnBody indent c) Format.nil
|
||||
| (FnBody.jmp j ys) := "jmp " ++ format j ++ formatArray ys
|
||||
| (FnBody.ret x) := "ret " ++ format x
|
||||
| FnBody.unreachable := "⊥"
|
||||
|
||||
instance fnBodyHasFormat : HasFormat FnBody := ⟨formatFnBody⟩
|
||||
instance fnBodyHasToString : HasToString FnBody := ⟨λ b, (format b).pretty⟩
|
||||
instance fnBodyHasToString : HasToString FnBody := ⟨fun b => (format b).pretty⟩
|
||||
|
||||
def formatDecl (indent : Nat := 2) : Decl → Format
|
||||
| (Decl.fdecl f xs ty b) := "def " ++ format f ++ formatParams xs ++ format " : " ++ format ty ++ " :=" ++ Format.nest indent (Format.line ++ formatFnBody indent b)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace MaxIndex
|
|||
abbrev Collector := Index → Index
|
||||
|
||||
@[inline] private def skip : Collector := id
|
||||
@[inline] private def collect (x : Index) : Collector := λ y, if x > y then x else y
|
||||
@[inline] private def collect (x : Index) : Collector := fun y => if x > y then x else y
|
||||
@[inline] private def collectVar (x : VarId) : Collector := collect x.idx
|
||||
@[inline] private def collectJP (j : JoinPointId) : Collector := collect j.idx
|
||||
@[inline] private def seq (k₁ k₂ : Collector) : Collector := k₂ ∘ k₁
|
||||
|
|
@ -32,7 +32,7 @@ private def collectArg : Arg → Collector
|
|||
| irrelevant := skip
|
||||
|
||||
@[specialize] private def collectArray {α : Type} (as : Array α) (f : α → Collector) : Collector :=
|
||||
λ m, as.foldl (λ m a, f a m) m
|
||||
fun m => as.foldl (fun m a => f a m) m
|
||||
|
||||
private def collectArgs (as : Array Arg) : Collector := collectArray as collectArg
|
||||
private def collectParam (p : Param) : Collector := collectVar p.x
|
||||
|
|
@ -55,7 +55,7 @@ private def collectExpr : Expr → Collector
|
|||
| (Expr.isTaggedPtr x) := collectVar x
|
||||
|
||||
private def collectAlts (f : FnBody → Collector) (alts : Array Alt) : Collector :=
|
||||
collectArray alts $ λ alt, f alt.body
|
||||
collectArray alts $ fun alt => f alt.body
|
||||
|
||||
partial def collectFnBody : FnBody → Collector
|
||||
| (FnBody.vdecl x _ v b) := collectExpr v >> collectFnBody b
|
||||
|
|
@ -92,10 +92,10 @@ namespace FreeIndices
|
|||
abbrev Collector := IndexSet → IndexSet → IndexSet
|
||||
|
||||
@[inline] private def skip : Collector :=
|
||||
λ bv fv, fv
|
||||
fun bv fv => fv
|
||||
|
||||
@[inline] private def collectIndex (x : Index) : Collector :=
|
||||
λ bv fv, if bv.contains x then fv else fv.insert x
|
||||
fun bv fv => if bv.contains x then fv else fv.insert x
|
||||
|
||||
@[inline] private def collectVar (x : VarId) : Collector :=
|
||||
collectIndex x.idx
|
||||
|
|
@ -104,7 +104,7 @@ collectIndex x.idx
|
|||
collectIndex x.idx
|
||||
|
||||
@[inline] private def withIndex (x : Index) : Collector → Collector :=
|
||||
λ k bv fv, k (bv.insert x) fv
|
||||
fun k bv fv => k (bv.insert x) fv
|
||||
|
||||
@[inline] private def withVar (x : VarId) : Collector → Collector :=
|
||||
withIndex x.idx
|
||||
|
|
@ -113,13 +113,13 @@ withIndex x.idx
|
|||
withIndex x.idx
|
||||
|
||||
def insertParams (s : IndexSet) (ys : Array Param) : IndexSet :=
|
||||
ys.foldl (λ s p, s.insert p.x.idx) s
|
||||
ys.foldl (fun s p => s.insert p.x.idx) s
|
||||
|
||||
@[inline] private def withParams (ys : Array Param) : Collector → Collector :=
|
||||
λ k bv fv, k (insertParams bv ys) fv
|
||||
fun k bv fv => k (insertParams bv ys) fv
|
||||
|
||||
@[inline] private def seq : Collector → Collector → Collector :=
|
||||
λ k₁ k₂ bv fv, k₂ bv (k₁ bv fv)
|
||||
fun k₁ k₂ bv fv => k₂ bv (k₁ bv fv)
|
||||
|
||||
instance : HasAndthen Collector := ⟨seq⟩
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ private def collectArg : Arg → Collector
|
|||
| irrelevant := skip
|
||||
|
||||
@[specialize] private def collectArray {α : Type} (as : Array α) (f : α → Collector) : Collector :=
|
||||
λ bv fv, as.foldl (λ fv a, f a bv fv) fv
|
||||
fun bv fv => as.foldl (fun fv a => f a bv fv) fv
|
||||
|
||||
private def collectArgs (as : Array Arg) : Collector :=
|
||||
collectArray as collectArg
|
||||
|
|
@ -150,7 +150,7 @@ private def collectExpr : Expr → Collector
|
|||
| (Expr.isTaggedPtr x) := collectVar x
|
||||
|
||||
private def collectAlts (f : FnBody → Collector) (alts : Array Alt) : Collector :=
|
||||
collectArray alts $ λ alt, f alt.body
|
||||
collectArray alts $ fun alt => f alt.body
|
||||
|
||||
partial def collectFnBody : FnBody → Collector
|
||||
| (FnBody.vdecl x _ v b) := collectExpr v >> withVar x (collectFnBody b)
|
||||
|
|
@ -192,7 +192,7 @@ def visitArgs (w : Index) (xs : Array Arg) : Bool :=
|
|||
xs.any (visitArg w)
|
||||
|
||||
def visitParams (w : Index) (ps : Array Param) : Bool :=
|
||||
ps.any (λ p, w == p.x.idx)
|
||||
ps.any (fun p => w == p.x.idx)
|
||||
|
||||
def visitExpr (w : Index) : Expr → Bool
|
||||
| (Expr.ctor _ ys) := visitArgs w ys
|
||||
|
|
@ -223,7 +223,7 @@ partial def visitFnBody (w : Index) : FnBody → Bool
|
|||
| (FnBody.mdata _ b) := visitFnBody b
|
||||
| (FnBody.jmp j ys) := visitJP w j || visitArgs w ys
|
||||
| (FnBody.ret x) := visitArg w x
|
||||
| (FnBody.case _ x alts) := visitVar w x || alts.any (λ alt, visitFnBody alt.body)
|
||||
| (FnBody.case _ x alts) := visitVar w x || alts.any (fun alt => visitFnBody alt.body)
|
||||
| (FnBody.unreachable) := false
|
||||
|
||||
end HasIndex
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ partial def visitFnBody (w : Index) : FnBody → M Bool
|
|||
pure false
|
||||
}
|
||||
| (FnBody.ret x) := visitArg w x
|
||||
| (FnBody.case _ x alts) := visitVar w x <||> alts.anyM (λ alt, visitFnBody alt.body)
|
||||
| (FnBody.case _ x alts) := visitVar w x <||> alts.anyM (fun alt => visitFnBody alt.body)
|
||||
| (FnBody.unreachable) := pure false
|
||||
|
||||
end IsLive
|
||||
|
|
@ -84,7 +84,7 @@ def FnBody.hasLiveVar (b : FnBody) (ctx : LocalContext) (x : VarId) : Bool :=
|
|||
(IsLive.visitFnBody x.idx b).run' ctx
|
||||
|
||||
abbrev LiveVarSet := VarIdSet
|
||||
abbrev JPLiveVarMap := RBMap JoinPointId LiveVarSet (λ j₁ j₂, j₁.idx < j₂.idx)
|
||||
abbrev JPLiveVarMap := RBMap JoinPointId LiveVarSet (fun j₁ j₂ => j₁.idx < j₂.idx)
|
||||
|
||||
instance LiveVarSet.inhabited : Inhabited LiveVarSet := ⟨{}⟩
|
||||
|
||||
|
|
@ -92,25 +92,25 @@ namespace LiveVars
|
|||
|
||||
abbrev Collector := LiveVarSet → LiveVarSet
|
||||
|
||||
@[inline] private def skip : Collector := λ s, s
|
||||
@[inline] private def collectVar (x : VarId) : Collector := λ s, s.insert x
|
||||
@[inline] private def skip : Collector := fun s => s
|
||||
@[inline] private def collectVar (x : VarId) : Collector := fun s => s.insert x
|
||||
private def collectArg : Arg → Collector
|
||||
| (Arg.var x) := collectVar x
|
||||
| irrelevant := skip
|
||||
@[specialize] private def collectArray {α : Type} (as : Array α) (f : α → Collector) : Collector :=
|
||||
λ s, as.foldl (λ s a, f a s) s
|
||||
fun s => as.foldl (fun s a => f a s) s
|
||||
private def collectArgs (as : Array Arg) : Collector :=
|
||||
collectArray as collectArg
|
||||
private def accumulate (s' : LiveVarSet) : Collector :=
|
||||
λ s, s'.fold (λ s x, s.insert x) s
|
||||
fun s => s'.fold (fun s x => s.insert x) s
|
||||
private def collectJP (m : JPLiveVarMap) (j : JoinPointId) : Collector :=
|
||||
match m.find j with
|
||||
| some xs := accumulate xs
|
||||
| none := skip -- unreachable for well-formed code
|
||||
private def bindVar (x : VarId) : Collector :=
|
||||
λ s, s.erase x
|
||||
fun s => s.erase x
|
||||
private def bindParams (ps : Array Param) : Collector :=
|
||||
λ s, ps.foldl (λ s p, s.erase p.x) s
|
||||
fun s => ps.foldl (fun s p => s.erase p.x) s
|
||||
|
||||
def collectExpr : Expr → Collector
|
||||
| (Expr.ctor _ ys) := collectArgs ys
|
||||
|
|
@ -143,7 +143,7 @@ partial def collectFnBody : FnBody → JPLiveVarMap → Collector
|
|||
| (FnBody.del x b) m := collectVar x ∘ collectFnBody b m
|
||||
| (FnBody.mdata _ b) m := collectFnBody b m
|
||||
| (FnBody.ret x) m := collectArg x
|
||||
| (FnBody.case _ x alts) m := collectVar x ∘ collectArray alts (λ alt, collectFnBody alt.body m)
|
||||
| (FnBody.case _ x alts) m := collectVar x ∘ collectArray alts (fun alt => collectFnBody alt.body m)
|
||||
| (FnBody.unreachable) m := skip
|
||||
| (FnBody.jmp j xs) m := collectJP m j ∘ collectArgs xs
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,15 @@ abbrev M := StateT IndexSet Id
|
|||
def checkId (id : Index) : M Bool :=
|
||||
do found ← get;
|
||||
if found.contains id then pure false
|
||||
else modify (λ s, s.insert id) *> pure true
|
||||
else modify (fun s => s.insert id) *> pure true
|
||||
|
||||
def checkParams (ps : Array Param) : M Bool :=
|
||||
ps.allM $ λ p, checkId p.x.idx
|
||||
ps.allM $ fun p => checkId p.x.idx
|
||||
|
||||
partial def checkFnBody : FnBody → M Bool
|
||||
| (FnBody.vdecl x _ _ b) := checkId x.idx <&&> checkFnBody b
|
||||
| (FnBody.jdecl j ys _ b) := checkId j.idx <&&> checkParams ys <&&> checkFnBody b
|
||||
| (FnBody.case _ _ alts) := alts.allM $ λ alt, checkFnBody alt.body
|
||||
| (FnBody.case _ _ alts) := alts.allM $ fun alt => checkFnBody alt.body
|
||||
| b := if b.isTerminal then pure true else checkFnBody b.body
|
||||
|
||||
partial def checkDecl : Decl → M Bool
|
||||
|
|
@ -43,7 +43,7 @@ namespace NormalizeIds
|
|||
abbrev M := ReaderT IndexRenaming Id
|
||||
|
||||
def normIndex (x : Index) : M Index :=
|
||||
λ m, match m.find x with
|
||||
fun m => match m.find x with
|
||||
| some y := y
|
||||
| none := x
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ def normArg : Arg → M Arg
|
|||
| other := pure other
|
||||
|
||||
def normArgs (as : Array Arg) : M (Array Arg) :=
|
||||
λ m, as.map $ λ a, normArg a m
|
||||
fun m => as.map $ fun a => normArg a m
|
||||
|
||||
def normExpr : Expr → M Expr
|
||||
| (Expr.ctor c ys) m := Expr.ctor c (normArgs ys m)
|
||||
|
|
@ -79,29 +79,29 @@ def normExpr : Expr → M Expr
|
|||
abbrev N := ReaderT IndexRenaming (State Nat)
|
||||
|
||||
@[inline] def withVar {α : Type} (x : VarId) (k : VarId → N α) : N α :=
|
||||
λ m, do
|
||||
n ← getModify (λ n, n + 1);
|
||||
fun m => do
|
||||
n ← getModify (fun n => n + 1);
|
||||
k { idx := n } (m.insert x.idx n)
|
||||
|
||||
@[inline] def withJP {α : Type} (x : JoinPointId) (k : JoinPointId → N α) : N α :=
|
||||
λ m, do
|
||||
n ← getModify (λ n, n + 1);
|
||||
fun m => do
|
||||
n ← getModify (fun n => n + 1);
|
||||
k { idx := n } (m.insert x.idx n)
|
||||
|
||||
@[inline] def withParams {α : Type} (ps : Array Param) (k : Array Param → N α) : N α :=
|
||||
λ m, do
|
||||
m ← ps.mfoldl (λ (m : IndexRenaming) p, do n ← getModify (λ n, n + 1); pure $ m.insert p.x.idx n) m;
|
||||
let ps := ps.map $ λ p, { x := normVar p.x m, .. p };
|
||||
fun m => do
|
||||
m ← ps.mfoldl (fun (m : IndexRenaming) p => do n ← getModify (fun n => n + 1); pure $ m.insert p.x.idx n) m;
|
||||
let ps := ps.map $ fun p => { x := normVar p.x m, .. p };
|
||||
k ps m
|
||||
|
||||
instance MtoN {α} : HasCoe (M α) (N α) :=
|
||||
⟨λ x m, pure $ x m⟩
|
||||
⟨fun x m => pure $ x m⟩
|
||||
|
||||
partial def normFnBody : FnBody → N FnBody
|
||||
| (FnBody.vdecl x t v b) := do v ← normExpr v; withVar x $ λ x, FnBody.vdecl x t v <$> normFnBody b
|
||||
| (FnBody.vdecl x t v b) := do v ← normExpr v; withVar x $ fun x => FnBody.vdecl x t v <$> normFnBody b
|
||||
| (FnBody.jdecl j ys v b) := do
|
||||
(ys, v) ← withParams ys $ λ ys, do { v ← normFnBody v; pure (ys, v) };
|
||||
withJP j $ λ j, FnBody.jdecl j ys v <$> normFnBody b
|
||||
(ys, v) ← withParams ys $ fun ys => do { v ← normFnBody v; pure (ys, v) };
|
||||
withJP j $ fun j => FnBody.jdecl j ys v <$> normFnBody b
|
||||
| (FnBody.set x i y b) := do x ← normVar x; y ← normArg y; FnBody.set x i y <$> normFnBody b
|
||||
| (FnBody.uset x i y b) := do x ← normVar x; y ← normVar y; FnBody.uset x i y <$> normFnBody b
|
||||
| (FnBody.sset x i o y t b) := do x ← normVar x; y ← normVar y; FnBody.sset x i o y t <$> normFnBody b
|
||||
|
|
@ -112,14 +112,14 @@ partial def normFnBody : FnBody → N FnBody
|
|||
| (FnBody.mdata d b) := FnBody.mdata d <$> normFnBody b
|
||||
| (FnBody.case tid x alts) := do
|
||||
x ← normVar x;
|
||||
alts ← alts.mmap $ λ alt, alt.mmodifyBody normFnBody;
|
||||
alts ← alts.mmap $ fun alt => alt.mmodifyBody normFnBody;
|
||||
pure $ FnBody.case tid x alts
|
||||
| (FnBody.jmp j ys) := FnBody.jmp <$> normJP j <*> normArgs ys
|
||||
| (FnBody.ret x) := FnBody.ret <$> normArg x
|
||||
| FnBody.unreachable := pure FnBody.unreachable
|
||||
|
||||
def normDecl : Decl → N Decl
|
||||
| (Decl.fdecl f xs t b) := withParams xs $ λ xs, Decl.fdecl f xs t <$> normFnBody b
|
||||
| (Decl.fdecl f xs t b) := withParams xs $ fun xs => Decl.fdecl f xs t <$> normFnBody b
|
||||
| other := pure other
|
||||
|
||||
end NormalizeIds
|
||||
|
|
@ -166,7 +166,7 @@ as.map (mapArg f)
|
|||
| (FnBody.dec x n c b) := FnBody.dec (f x) n c (mapFnBody b)
|
||||
| (FnBody.del x b) := FnBody.del (f x) (mapFnBody b)
|
||||
| (FnBody.mdata d b) := FnBody.mdata d (mapFnBody b)
|
||||
| (FnBody.case tid x alts) := FnBody.case tid (f x) (alts.map (λ alt, alt.modifyBody mapFnBody))
|
||||
| (FnBody.case tid x alts) := FnBody.case tid (f x) (alts.map (fun alt => alt.modifyBody mapFnBody))
|
||||
| (FnBody.jmp j ys) := FnBody.jmp j (mapArgs f ys)
|
||||
| (FnBody.ret x) := FnBody.ret (mapArg f x)
|
||||
| FnBody.unreachable := FnBody.unreachable
|
||||
|
|
@ -178,7 +178,7 @@ MapVars.mapFnBody f b
|
|||
|
||||
/- Replace `x` with `y` in `b`. This function assumes `b` does not shadow `x` -/
|
||||
def FnBody.replaceVar (x y : VarId) (b : FnBody) : FnBody :=
|
||||
b.mapVars $ λ z, if x == z then y else z
|
||||
b.mapVars $ fun z => if x == z then y else z
|
||||
|
||||
end IR
|
||||
end Lean
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ partial def pushProjs : Array FnBody → Array Alt → Array IndexSet → Array
|
|||
let skip (_ : Unit) := pushProjs bs alts altsF (ctx.push b) (b.collectFreeIndices ctxF);
|
||||
let push (x : VarId) (t : IRType) (v : Expr) :=
|
||||
if !ctxF.contains x.idx then
|
||||
let alts := alts.mapIdx $ λ i alt, alt.modifyBody $ λ b',
|
||||
let alts := alts.mapIdx $ fun i alt => alt.modifyBody $ fun b' =>
|
||||
if (altsF.get i).contains x.idx then b.setBody b'
|
||||
else b';
|
||||
let altsF := altsF.map $ λ s, if s.contains x.idx then b.collectFreeIndices s else s;
|
||||
let altsF := altsF.map $ fun s => if s.contains x.idx then b.collectFreeIndices s else s;
|
||||
pushProjs bs alts altsF ctx ctxF
|
||||
else
|
||||
skip ();
|
||||
|
|
@ -44,9 +44,9 @@ partial def FnBody.pushProj : FnBody → FnBody
|
|||
let bs := modifyJPs bs FnBody.pushProj;
|
||||
match term with
|
||||
| FnBody.case tid x alts :=
|
||||
let altsF := alts.map $ λ alt, alt.body.freeIndices;
|
||||
let altsF := alts.map $ fun alt => alt.body.freeIndices;
|
||||
let (bs, alts) := pushProjs bs alts altsF Array.empty {x.idx};
|
||||
let alts := alts.map $ λ alt, alt.modifyBody FnBody.pushProj;
|
||||
let alts := alts.map $ fun alt => alt.modifyBody FnBody.pushProj;
|
||||
let term := FnBody.case tid x alts;
|
||||
reshape bs term
|
||||
| other := reshape bs term
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ structure VarInfo :=
|
|||
(persistent : Bool := false) -- true if the variable is statically known to be marked a Persistent at runtime
|
||||
(consume : Bool := false) -- true if the variable RC must be "consumed"
|
||||
|
||||
abbrev VarMap := RBMap VarId VarInfo (λ x y, x.idx < y.idx)
|
||||
abbrev VarMap := RBMap VarId VarInfo (fun x y => x.idx < y.idx)
|
||||
|
||||
structure Context :=
|
||||
(env : Environment)
|
||||
|
|
@ -70,26 +70,26 @@ else let m := ctx.varMap;
|
|||
|
||||
private def addDecForAlt (ctx : Context) (caseLiveVars altLiveVars : LiveVarSet) (b : FnBody) : FnBody :=
|
||||
caseLiveVars.fold
|
||||
(λ b x, if !altLiveVars.contains x && mustConsume ctx x then addDec x b else b)
|
||||
(fun b x => if !altLiveVars.contains x && mustConsume ctx x then addDec x b else b)
|
||||
b
|
||||
|
||||
/- `isFirstOcc xs x i = true` if `xs[i]` is the first occurrence of `xs[i]` in `xs` -/
|
||||
private def isFirstOcc (xs : Array Arg) (i : Nat) : Bool :=
|
||||
let x := xs.get i;
|
||||
i.all $ λ j, xs.get j != x
|
||||
i.all $ fun j => xs.get j != x
|
||||
|
||||
/- Return true if `x` also occurs in `ys` in a position that is not consumed.
|
||||
That is, it is also passed as a borrow reference. -/
|
||||
@[specialize]
|
||||
private def isBorrowParamAux (x : VarId) (ys : Array Arg) (consumeParamPred : Nat → Bool) : Bool :=
|
||||
ys.size.any $ λ i,
|
||||
ys.size.any $ fun i =>
|
||||
let y := ys.get i;
|
||||
match y with
|
||||
| Arg.irrelevant := false
|
||||
| Arg.var y := x == y && !consumeParamPred i
|
||||
|
||||
private def isBorrowParam (x : VarId) (ys : Array Arg) (ps : Array Param) : Bool :=
|
||||
isBorrowParamAux x ys (λ i, !(ps.get i).borrow)
|
||||
isBorrowParamAux x ys (fun i => !(ps.get i).borrow)
|
||||
|
||||
/-
|
||||
Return `n`, the number of times `x` is consumed.
|
||||
|
|
@ -99,7 +99,7 @@ Return `n`, the number of times `x` is consumed.
|
|||
@[specialize]
|
||||
private def getNumConsumptions (x : VarId) (ys : Array Arg) (consumeParamPred : Nat → Bool) : Nat :=
|
||||
ys.size.fold
|
||||
(λ i n,
|
||||
(fun i n =>
|
||||
let y := ys.get i;
|
||||
match y with
|
||||
| Arg.irrelevant := n
|
||||
|
|
@ -109,7 +109,7 @@ ys.size.fold
|
|||
@[specialize]
|
||||
private def addIncBeforeAux (ctx : Context) (xs : Array Arg) (consumeParamPred : Nat → Bool) (b : FnBody) (liveVarsAfter : LiveVarSet) : FnBody :=
|
||||
xs.size.fold
|
||||
(λ i b,
|
||||
(fun i b =>
|
||||
let x := xs.get i;
|
||||
match x with
|
||||
| Arg.irrelevant := b
|
||||
|
|
@ -126,17 +126,17 @@ xs.size.fold
|
|||
else numConsuptions - 1;
|
||||
-- dbgTrace ("addInc " ++ toString x ++ " nconsumptions: " ++ toString numConsuptions ++ " incs: " ++ toString numIncs
|
||||
-- ++ " consume: " ++ toString info.consume ++ " live: " ++ toString (liveVarsAfter.contains x)
|
||||
-- ++ " borrowParam : " ++ toString (isBorrowParamAux x xs consumeParamPred)) $ λ _,
|
||||
-- ++ " borrowParam : " ++ toString (isBorrowParamAux x xs consumeParamPred)) $ fun _ =>
|
||||
addInc x b numIncs)
|
||||
b
|
||||
|
||||
private def addIncBefore (ctx : Context) (xs : Array Arg) (ps : Array Param) (b : FnBody) (liveVarsAfter : LiveVarSet) : FnBody :=
|
||||
addIncBeforeAux ctx xs (λ i, !(ps.get i).borrow) b liveVarsAfter
|
||||
addIncBeforeAux ctx xs (fun i => !(ps.get i).borrow) b liveVarsAfter
|
||||
|
||||
/- See `addIncBeforeAux`/`addIncBefore` for the procedure that inserts `inc` operations before an application. -/
|
||||
private def addDecAfterFullApp (ctx : Context) (xs : Array Arg) (ps : Array Param) (b : FnBody) (bLiveVars : LiveVarSet) : FnBody :=
|
||||
xs.size.fold
|
||||
(λ i b,
|
||||
(fun i b =>
|
||||
match xs.get i with
|
||||
| Arg.irrelevant := b
|
||||
| Arg.var x :=
|
||||
|
|
@ -150,13 +150,13 @@ xs.size.fold
|
|||
b
|
||||
|
||||
private def addIncBeforeConsumeAll (ctx : Context) (xs : Array Arg) (b : FnBody) (liveVarsAfter : LiveVarSet) : FnBody :=
|
||||
addIncBeforeAux ctx xs (λ i, true) b liveVarsAfter
|
||||
addIncBeforeAux ctx xs (fun i => true) b liveVarsAfter
|
||||
|
||||
/- Add `dec` instructions for parameters that are references, are not alive in `b`, and are not borrow.
|
||||
That is, we must make sure these parameters are consumed. -/
|
||||
private def addDecForDeadParams (ps : Array Param) (b : FnBody) (bLiveVars : LiveVarSet) : FnBody :=
|
||||
ps.foldl
|
||||
(λ b p, if !p.borrow && p.ty.isObj && !bLiveVars.contains p.x then addDec p.x b else b)
|
||||
(fun b p => if !p.borrow && p.ty.isObj && !bLiveVars.contains p.x then addDec p.x b else b)
|
||||
b
|
||||
|
||||
private def isPersistent : Expr → Bool
|
||||
|
|
@ -189,7 +189,7 @@ private def addDecIfNeeded (ctx : Context) (x : VarId) (b : FnBody) (bLiveVars :
|
|||
if mustConsume ctx x && !bLiveVars.contains x then addDec x b else b
|
||||
|
||||
private def processVDecl (ctx : Context) (z : VarId) (t : IRType) (v : Expr) (b : FnBody) (bLiveVars : LiveVarSet) : FnBody × LiveVarSet :=
|
||||
-- dbgTrace ("processVDecl " ++ toString z ++ " " ++ toString (format v)) $ λ _,
|
||||
-- dbgTrace ("processVDecl " ++ toString z ++ " " ++ toString (format v)) $ fun _ =>
|
||||
let b := match v with
|
||||
| (Expr.ctor _ ys) := addIncBeforeConsumeAll ctx ys (FnBody.vdecl z t v b) bLiveVars
|
||||
| (Expr.reuse _ _ _ ys) := addIncBeforeConsumeAll ctx ys (FnBody.vdecl z t v b) bLiveVars
|
||||
|
|
@ -200,7 +200,7 @@ let b := match v with
|
|||
| (Expr.uproj _ x) := FnBody.vdecl z t v (addDecIfNeeded ctx x b bLiveVars)
|
||||
| (Expr.sproj _ _ x) := FnBody.vdecl z t v (addDecIfNeeded ctx x b bLiveVars)
|
||||
| (Expr.fap f ys) :=
|
||||
-- dbgTrace ("processVDecl " ++ toString v) $ λ _,
|
||||
-- dbgTrace ("processVDecl " ++ toString v) $ fun _ =>
|
||||
let ps := (getDecl ctx f).params;
|
||||
let b := addDecAfterFullApp ctx ys ps b bLiveVars;
|
||||
let b := FnBody.vdecl z t v b;
|
||||
|
|
@ -216,7 +216,7 @@ let liveVars := liveVars.erase z;
|
|||
(b, liveVars)
|
||||
|
||||
def updateVarInfoWithParams (ctx : Context) (ps : Array Param) : Context :=
|
||||
let m := ps.foldl (λ (m : VarMap) p, m.insert p.x { ref := p.ty.isObj, consume := !p.borrow }) ctx.varMap;
|
||||
let m := ps.foldl (fun (m : VarMap) p => m.insert p.x { ref := p.ty.isObj, consume := !p.borrow }) ctx.varMap;
|
||||
{ varMap := m, .. ctx }
|
||||
|
||||
partial def visitFnBody : FnBody → Context → (FnBody × LiveVarSet)
|
||||
|
|
@ -245,7 +245,7 @@ partial def visitFnBody : FnBody → Context → (FnBody × LiveVarSet)
|
|||
(FnBody.mdata m b, s)
|
||||
| b@(FnBody.case tid x alts) ctx :=
|
||||
let caseLiveVars := collectLiveVars b ctx.jpLiveVarMap;
|
||||
let alts := alts.map $ λ alt, match alt with
|
||||
let alts := alts.map $ fun alt => match alt with
|
||||
| Alt.ctor c b :=
|
||||
let ctx := updateRefUsingCtorInfo ctx x c;
|
||||
let (b, altLiveVars) := visitFnBody b ctx;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ private partial def S (w : VarId) (c : CtorInfo) : FnBody → FnBody
|
|||
let v' := S v;
|
||||
if v == v' then FnBody.jdecl j ys v (S b)
|
||||
else FnBody.jdecl j ys v' b
|
||||
| (FnBody.case tid x alts) := FnBody.case tid x $ alts.map $ λ alt, alt.modifyBody S
|
||||
| (FnBody.case tid x alts) := FnBody.case tid x $ alts.map $ fun alt => alt.modifyBody S
|
||||
| b :=
|
||||
if b.isTerminal then b
|
||||
else let
|
||||
|
|
@ -59,7 +59,7 @@ private partial def S (w : VarId) (c : CtorInfo) : FnBody → FnBody
|
|||
abbrev M := ReaderT LocalContext (StateT Index Id)
|
||||
|
||||
private def mkFresh : M VarId :=
|
||||
do idx ← getModify (λ n, n + 1);
|
||||
do idx ← getModify (fun n => n + 1);
|
||||
pure { idx := idx }
|
||||
|
||||
private def tryS (x : VarId) (c : CtorInfo) (b : FnBody) : M FnBody :=
|
||||
|
|
@ -73,7 +73,7 @@ private def Dfinalize (x : VarId) (c : CtorInfo) : FnBody × Bool → M FnBody
|
|||
| (b, false) := tryS x c b
|
||||
|
||||
private def argsContainsVar (ys : Array Arg) (x : VarId) : Bool :=
|
||||
ys.any $ λ arg, match arg with
|
||||
ys.any $ fun arg => match arg with
|
||||
| Arg.var y := x == y
|
||||
| _ := false
|
||||
|
||||
|
|
@ -93,11 +93,11 @@ private partial def Dmain (x : VarId) (c : CtorInfo) : FnBody → M (FnBody × B
|
|||
ctx ← read;
|
||||
if e.hasLiveVar ctx x then do
|
||||
/- If `x` is live in `e`, we recursively process each branch. -/
|
||||
alts ← alts.mmap $ λ alt, alt.mmodifyBody (λ b, Dmain b >>= Dfinalize x c);
|
||||
alts ← alts.mmap $ fun alt => alt.mmodifyBody (fun b => Dmain b >>= Dfinalize x c);
|
||||
pure (FnBody.case tid y alts, true)
|
||||
else pure (e, false)
|
||||
| (FnBody.jdecl j ys v b) := do
|
||||
(b, _) ← adaptReader (λ ctx : LocalContext, ctx.addJP j ys v) (Dmain b);
|
||||
(b, _) ← adaptReader (fun ctx : LocalContext => ctx.addJP j ys v) (Dmain b);
|
||||
(v, found) ← Dmain v;
|
||||
/- If `found == true`, then `Dmain b` must also have returned `(b, true)` since
|
||||
we assume the IR does not have dead join points. So, if `x` is live in `j`,
|
||||
|
|
@ -129,7 +129,7 @@ Dmain x c b >>= Dfinalize x c
|
|||
|
||||
partial def R : FnBody → M FnBody
|
||||
| (FnBody.case tid x alts) := do
|
||||
alts ← alts.mmap $ λ alt, do {
|
||||
alts ← alts.mmap $ fun alt => do {
|
||||
alt ← alt.mmodifyBody R;
|
||||
match alt with
|
||||
| Alt.ctor c b :=
|
||||
|
|
@ -140,7 +140,7 @@ partial def R : FnBody → M FnBody
|
|||
pure $ FnBody.case tid x alts
|
||||
| (FnBody.jdecl j ys v b) := do
|
||||
v ← R v;
|
||||
b ← adaptReader (λ ctx : LocalContext, ctx.addJP j ys v) (R b);
|
||||
b ← adaptReader (fun (ctx : LocalContext) => ctx.addJP j ys v) (R b);
|
||||
pure $ FnBody.jdecl j ys v b
|
||||
| e := do
|
||||
if e.isTerminal then pure e
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ else
|
|||
|
||||
private def getOccsOf (alts : Array Alt) (i : Nat) : Nat :=
|
||||
let aBody := (alts.get i).body;
|
||||
alts.iterateFrom 1 (i + 1) $ λ _ a' n,
|
||||
alts.iterateFrom 1 (i + 1) $ fun _ a' n =>
|
||||
if a'.body == aBody then n+1 else n
|
||||
|
||||
private def maxOccs (alts : Array Alt) : Alt × Nat :=
|
||||
alts.iterateFrom (alts.get 0, getOccsOf alts 0) 1 $ λ i a p,
|
||||
alts.iterateFrom (alts.get 0, getOccsOf alts 0) 1 $ fun i a p =>
|
||||
let noccs := getOccsOf alts i.val;
|
||||
if noccs > p.2 then (alts.fget i, noccs) else p
|
||||
|
||||
|
|
@ -34,11 +34,11 @@ else
|
|||
let (max, noccs) := maxOccs alts;
|
||||
if noccs == 1 then alts
|
||||
else
|
||||
let alts := alts.filter $ (λ alt, alt.body != max.body);
|
||||
let alts := alts.filter $ (fun alt => alt.body != max.body);
|
||||
alts.push (Alt.default max.body)
|
||||
|
||||
private def mkSimpCase (tid : Name) (x : VarId) (alts : Array Alt) : FnBody :=
|
||||
let alts := alts.filter (λ alt, alt.body != FnBody.unreachable);
|
||||
let alts := alts.filter (fun alt => alt.body != FnBody.unreachable);
|
||||
let alts := addDefault alts;
|
||||
if alts.size == 0 then
|
||||
FnBody.unreachable
|
||||
|
|
@ -53,7 +53,7 @@ partial def FnBody.simpCase : FnBody → FnBody
|
|||
let bs := modifyJPs bs FnBody.simpCase;
|
||||
match term with
|
||||
| FnBody.case tid x alts :=
|
||||
let alts := alts.map $ λ alt, alt.modifyBody FnBody.simpCase;
|
||||
let alts := alts.map $ fun alt => alt.modifyBody FnBody.simpCase;
|
||||
reshape bs (mkSimpCase tid x alts)
|
||||
| other := reshape bs term
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ def mkSpecializeAttrs : IO (EnumAttributes SpecializeAttributeKind) :=
|
|||
registerEnumAttributes `specializeAttrs
|
||||
[(`specialize, "mark definition to always be inlined", SpecializeAttributeKind.specialize),
|
||||
(`nospecialize, "mark definition to never be inlined", SpecializeAttributeKind.nospecialize) ]
|
||||
(λ env declName _, checkIsDefinition env declName)
|
||||
(fun env declName _ => checkIsDefinition env declName)
|
||||
|
||||
@[init mkSpecializeAttrs]
|
||||
constant specializeAttrs : EnumAttributes SpecializeAttributeKind := default _
|
||||
|
|
@ -84,7 +84,7 @@ def mkSpecExtension : IO (SimplePersistentEnvExtension SpecEntry SpecState) :=
|
|||
registerSimplePersistentEnvExtension {
|
||||
name := `specialize,
|
||||
addEntryFn := SpecState.addEntry,
|
||||
addImportedFn := λ es, (mkStateFromImportedEntries SpecState.addEntry {} es).switch
|
||||
addImportedFn := fun es => (mkStateFromImportedEntries SpecState.addEntry {} es).switch
|
||||
}
|
||||
|
||||
@[init mkSpecExtension]
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ structure AtMostOnceData :=
|
|||
def Visitor := AtMostOnceData → AtMostOnceData
|
||||
|
||||
@[inline] def seq (f g : Visitor) : Visitor :=
|
||||
λ d, match f d with
|
||||
fun d => match f d with
|
||||
| ⟨found, false⟩ := ⟨found, false⟩
|
||||
| other := g other
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ def isEagerLambdaLiftingName : Name → Bool
|
|||
@[export lean.get_decl_names_for_code_gen_core]
|
||||
private def getDeclNamesForCodeGen : Declaration → List Name
|
||||
| (Declaration.defnDecl { name := n, .. }) := [n]
|
||||
| (Declaration.mutualDefnDecl defs) := defs.map $ λ d, d.name
|
||||
| (Declaration.mutualDefnDecl defs) := defs.map $ fun d => d.name
|
||||
| _ := []
|
||||
|
||||
def checkIsDefinition (env : Environment) (n : Name) : Except String Unit :=
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ let s : EnvExtensionState := env.extensions.get ext.idx;
|
|||
constant getState {σ : Type} (ext : EnvExtension σ) (env : Environment) : σ := ext.initial
|
||||
|
||||
@[inline] unsafe def modifyStateUnsafe {σ : Type} (ext : EnvExtension σ) (env : Environment) (f : σ → σ) : Environment :=
|
||||
{ extensions := env.extensions.modify ext.idx $ λ s,
|
||||
{ extensions := env.extensions.modify ext.idx $ fun s =>
|
||||
let s : σ := (@unsafeCast _ _ ⟨ext.initial⟩ s);
|
||||
let s : σ := f s;
|
||||
unsafeCast s,
|
||||
|
|
@ -148,7 +148,7 @@ let ext : EnvExtension σ := {
|
|||
idx := idx,
|
||||
initial := initState
|
||||
};
|
||||
envExtensionsRef.modify (λ exts, exts.push (unsafeCast ext));
|
||||
envExtensionsRef.modify (fun exts => exts.push (unsafeCast ext));
|
||||
pure ext
|
||||
|
||||
/- Environment extensions can only be registered during initialization.
|
||||
|
|
@ -159,7 +159,7 @@ pure ext
|
|||
constant registerEnvExtension {σ : Type} (initState : σ) : IO (EnvExtension σ) := default _
|
||||
|
||||
private def mkInitialExtensionStates : IO (Array EnvExtensionState) :=
|
||||
do exts ← envExtensionsRef.get; pure $ exts.map $ λ ext, ext.initial
|
||||
do exts ← envExtensionsRef.get; pure $ exts.map $ fun ext => ext.initial
|
||||
|
||||
@[export lean.mk_empty_environment_core]
|
||||
def mkEmptyEnvironment (trustLevel : UInt32 := 0) : IO Environment :=
|
||||
|
|
@ -200,10 +200,10 @@ instance PersistentEnvExtensionState.inhabited {α σ} [Inhabited σ] : Inhabite
|
|||
instance PersistentEnvExtension.inhabited {α σ} [Inhabited σ] : Inhabited (PersistentEnvExtension α σ) :=
|
||||
⟨{ toEnvExtension := { idx := 0, initial := default _ },
|
||||
name := default _,
|
||||
addImportedFn := λ _, default _,
|
||||
addEntryFn := λ s _, s,
|
||||
exportEntriesFn := λ _, Array.empty,
|
||||
statsFn := λ _, Format.nil }⟩
|
||||
addImportedFn := fun _ => default _,
|
||||
addEntryFn := fun s _ => s,
|
||||
exportEntriesFn := fun _ => Array.empty,
|
||||
statsFn := fun _ => Format.nil }⟩
|
||||
|
||||
namespace PersistentEnvExtension
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ def getModuleEntries {α σ : Type} (ext : PersistentEnvExtension α σ) (env :
|
|||
(ext.toEnvExtension.getState env).importedEntries.get m
|
||||
|
||||
def addEntry {α σ : Type} (ext : PersistentEnvExtension α σ) (env : Environment) (a : α) : Environment :=
|
||||
ext.toEnvExtension.modifyState env $ λ s,
|
||||
ext.toEnvExtension.modifyState env $ fun s =>
|
||||
let state := ext.addEntryFn s.state a;
|
||||
{ state := state, .. s }
|
||||
|
||||
|
|
@ -219,10 +219,10 @@ def getState {α σ : Type} (ext : PersistentEnvExtension α σ) (env : Environm
|
|||
(ext.toEnvExtension.getState env).state
|
||||
|
||||
def setState {α σ : Type} (ext : PersistentEnvExtension α σ) (env : Environment) (s : σ) : Environment :=
|
||||
ext.toEnvExtension.modifyState env $ λ ps, { state := s, .. ps }
|
||||
ext.toEnvExtension.modifyState env $ fun ps => { state := s, .. ps }
|
||||
|
||||
def modifyState {α σ : Type} (ext : PersistentEnvExtension α σ) (env : Environment) (f : σ → σ) : Environment :=
|
||||
ext.toEnvExtension.modifyState env $ λ ps, { state := f (ps.state), .. ps }
|
||||
ext.toEnvExtension.modifyState env $ fun ps => { state := f (ps.state), .. ps }
|
||||
|
||||
end PersistentEnvExtension
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ structure PersistentEnvExtensionDescr (α σ : Type) :=
|
|||
(addImportedFn : Array (Array α) → σ)
|
||||
(addEntryFn : σ → α → σ)
|
||||
(exportEntriesFn : σ → Array α)
|
||||
(statsFn : σ → Format := λ _, Format.nil)
|
||||
(statsFn : σ → Format := fun _ => Format.nil)
|
||||
|
||||
unsafe def registerPersistentEnvExtensionUnsafe {α σ : Type} (descr : PersistentEnvExtensionDescr α σ) : IO (PersistentEnvExtension α σ) :=
|
||||
do
|
||||
|
|
@ -245,7 +245,7 @@ let s : PersistentEnvExtensionState α σ := {
|
|||
importedEntries := Array.empty,
|
||||
state := descr.addImportedFn Array.empty };
|
||||
pExts ← persistentEnvExtensionsRef.get;
|
||||
when (pExts.any (λ ext, ext.name == descr.name)) $ throw (IO.userError ("invalid environment extension, '" ++ toString descr.name ++ "' has already been used"));
|
||||
when (pExts.any (fun ext => ext.name == descr.name)) $ throw (IO.userError ("invalid environment extension, '" ++ toString descr.name ++ "' has already been used"));
|
||||
ext ← registerEnvExtension s;
|
||||
let pExt : PersistentEnvExtension α σ := {
|
||||
toEnvExtension := ext,
|
||||
|
|
@ -255,7 +255,7 @@ let pExt : PersistentEnvExtension α σ := {
|
|||
exportEntriesFn := descr.exportEntriesFn,
|
||||
statsFn := descr.statsFn
|
||||
};
|
||||
persistentEnvExtensionsRef.modify (λ pExts, pExts.push (unsafeCast pExt));
|
||||
persistentEnvExtensionsRef.modify (fun pExts => pExts.push (unsafeCast pExt));
|
||||
pure pExt
|
||||
|
||||
@[implementedBy registerPersistentEnvExtensionUnsafe]
|
||||
|
|
@ -266,22 +266,22 @@ constant registerPersistentEnvExtension {α σ : Type} (descr : PersistentEnvExt
|
|||
def SimplePersistentEnvExtension (α σ : Type) := PersistentEnvExtension α (List α × σ)
|
||||
|
||||
@[specialize] def mkStateFromImportedEntries {α σ : Type} (addEntryFn : σ → α → σ) (initState : σ) (as : Array (Array α)) : σ :=
|
||||
as.foldl (λ r es, es.foldl (λ r e, addEntryFn r e) r) initState
|
||||
as.foldl (fun r es => es.foldl (fun r e => addEntryFn r e) r) initState
|
||||
|
||||
structure SimplePersistentEnvExtensionDescr (α σ : Type) :=
|
||||
(name : Name)
|
||||
(addEntryFn : σ → α → σ)
|
||||
(addImportedFn : Array (Array α) → σ)
|
||||
(toArrayFn : List α → Array α := λ es, es.toArray)
|
||||
(toArrayFn : List α → Array α := fun es => es.toArray)
|
||||
|
||||
def registerSimplePersistentEnvExtension {α σ : Type} (descr : SimplePersistentEnvExtensionDescr α σ) : IO (SimplePersistentEnvExtension α σ) :=
|
||||
registerPersistentEnvExtension {
|
||||
name := descr.name,
|
||||
addImportedFn := λ as, ([], descr.addImportedFn as),
|
||||
addEntryFn := λ s e, match s with
|
||||
addImportedFn := fun as => ([], descr.addImportedFn as),
|
||||
addEntryFn := fun s e => match s with
|
||||
| (entries, s) := (e::entries, descr.addEntryFn s e),
|
||||
exportEntriesFn := λ s, descr.toArrayFn s.1.reverse,
|
||||
statsFn := λ s, format "number of local entries: " ++ format s.1.length
|
||||
exportEntriesFn := fun s => descr.toArrayFn s.1.reverse,
|
||||
statsFn := fun s => format "number of local entries: " ++ format s.1.length
|
||||
}
|
||||
|
||||
namespace SimplePersistentEnvExtension
|
||||
|
|
@ -296,10 +296,10 @@ def getState {α σ : Type} (ext : SimplePersistentEnvExtension α σ) (env : En
|
|||
(PersistentEnvExtension.getState ext env).2
|
||||
|
||||
def setState {α σ : Type} (ext : SimplePersistentEnvExtension α σ) (env : Environment) (s : σ) : Environment :=
|
||||
PersistentEnvExtension.modifyState ext env (λ ⟨entries, _⟩, (entries, s))
|
||||
PersistentEnvExtension.modifyState ext env (fun ⟨entries, _⟩ => (entries, s))
|
||||
|
||||
def modifyState {α σ : Type} (ext : SimplePersistentEnvExtension α σ) (env : Environment) (f : σ → σ) : Environment :=
|
||||
PersistentEnvExtension.modifyState ext env (λ ⟨entries, s⟩, (entries, f s))
|
||||
PersistentEnvExtension.modifyState ext env (fun ⟨entries, s⟩ => (entries, f s))
|
||||
|
||||
end SimplePersistentEnvExtension
|
||||
|
||||
|
|
@ -343,7 +343,7 @@ constant modListExtension : EnvExtension (List Modification) := default _
|
|||
/- The C++ code uses this function to store the given modification object into the environment. -/
|
||||
@[export lean.environment_add_modification_core]
|
||||
def addModification (env : Environment) (mod : Modification) : Environment :=
|
||||
modListExtension.modifyState env $ λ mods, mod :: mods
|
||||
modListExtension.modifyState env $ fun mods => mod :: mods
|
||||
|
||||
/- mkModuleData invokes this function to convert a list of modification objects into
|
||||
a serialized byte array. -/
|
||||
|
|
@ -373,7 +373,7 @@ def mkModuleData (env : Environment) : IO ModuleData :=
|
|||
do
|
||||
pExts ← persistentEnvExtensionsRef.get;
|
||||
let entries : Array (Name × Array EnvExtensionEntry) := pExts.size.fold
|
||||
(λ i result,
|
||||
(fun i result =>
|
||||
let state := (pExts.get i).getState env;
|
||||
let exportEntriesFn := (pExts.get i).exportEntriesFn;
|
||||
let extName := (pExts.get i).name;
|
||||
|
|
@ -382,7 +382,7 @@ let entries : Array (Name × Array EnvExtensionEntry) := pExts.size.fold
|
|||
bytes ← serializeModifications (modListExtension.getState env);
|
||||
pure {
|
||||
imports := env.header.imports,
|
||||
constants := env.constants.foldStage2 (λ cs _ c, cs.push c) Array.empty,
|
||||
constants := env.constants.foldStage2 (fun cs _ c => cs.push c) Array.empty,
|
||||
entries := entries,
|
||||
serialized := bytes
|
||||
}
|
||||
|
|
@ -418,29 +418,29 @@ private partial def getEntriesFor (mod : ModuleData) (extId : Name) : Nat → Ar
|
|||
private def setImportedEntries (env : Environment) (mods : Array ModuleData) : IO Environment :=
|
||||
do
|
||||
pExtDescrs ← persistentEnvExtensionsRef.get;
|
||||
pure $ mods.iterate env $ λ _ mod env,
|
||||
pExtDescrs.iterate env $ λ _ extDescr env,
|
||||
pure $ mods.iterate env $ fun _ mod env =>
|
||||
pExtDescrs.iterate env $ fun _ extDescr env =>
|
||||
let entries := getEntriesFor mod extDescr.name 0;
|
||||
extDescr.toEnvExtension.modifyState env $ λ s,
|
||||
extDescr.toEnvExtension.modifyState env $ fun s =>
|
||||
{ importedEntries := s.importedEntries.push entries,
|
||||
.. s }
|
||||
|
||||
private def finalizePersistentExtensions (env : Environment) : IO Environment :=
|
||||
do
|
||||
pExtDescrs ← persistentEnvExtensionsRef.get;
|
||||
pure $ pExtDescrs.iterate env $ λ _ extDescr env,
|
||||
extDescr.toEnvExtension.modifyState env $ λ s,
|
||||
pure $ pExtDescrs.iterate env $ fun _ extDescr env =>
|
||||
extDescr.toEnvExtension.modifyState env $ fun s =>
|
||||
{ state := extDescr.addImportedFn s.importedEntries, .. s }
|
||||
|
||||
@[export lean.import_modules_core]
|
||||
def importModules (modNames : List Name) (trustLevel : UInt32 := 0) : IO Environment :=
|
||||
do
|
||||
(_, mods) ← importModulesAux modNames ({}, Array.empty);
|
||||
let const2ModIdx := mods.iterate {} $ λ modIdx (mod : ModuleData) (m : HashMap Name ModuleIdx),
|
||||
mod.constants.iterate m $ λ _ cinfo m,
|
||||
let const2ModIdx := mods.iterate {} $ fun (modIdx) (mod : ModuleData) (m : HashMap Name ModuleIdx) =>
|
||||
mod.constants.iterate m $ fun _ cinfo m =>
|
||||
m.insert cinfo.name modIdx.val;
|
||||
constants ← mods.miterate SMap.empty $ λ _ (mod : ModuleData) (cs : ConstMap),
|
||||
mod.constants.miterate cs $ λ _ cinfo cs, do {
|
||||
constants ← mods.miterate SMap.empty $ fun _ (mod : ModuleData) (cs : ConstMap) =>
|
||||
mod.constants.miterate cs $ fun _ cinfo cs => do {
|
||||
when (cs.contains cinfo.name) $ throw (IO.userError ("import failed, environment already contains '" ++ toString cinfo.name ++ "'"));
|
||||
pure $ cs.insert cinfo.name cinfo
|
||||
};
|
||||
|
|
@ -458,7 +458,7 @@ let env : Environment := {
|
|||
};
|
||||
env ← setImportedEntries env mods;
|
||||
env ← finalizePersistentExtensions env;
|
||||
env ← mods.miterate env $ λ _ mod env, performModifications env mod.serialized;
|
||||
env ← mods.miterate env $ fun _ mod env => performModifications env mod.serialized;
|
||||
pure env
|
||||
|
||||
namespace Environment
|
||||
|
|
@ -477,12 +477,12 @@ IO.println ("number of buckets for imported consts: " ++ toString env.constants.
|
|||
IO.println ("map depth for local consts: " ++ toString env.constants.maxDepth);
|
||||
IO.println ("trust level: " ++ toString env.header.trustLevel);
|
||||
IO.println ("number of extensions: " ++ toString env.extensions.size);
|
||||
pExtDescrs.mfor $ λ extDescr, do {
|
||||
pExtDescrs.mfor $ fun extDescr => do {
|
||||
IO.println ("extension '" ++ toString extDescr.name ++ "'");
|
||||
let s := extDescr.toEnvExtension.getState env;
|
||||
let fmt := extDescr.statsFn s.state;
|
||||
unless fmt.isNil (IO.println (" " ++ toString (Format.nest 2 (extDescr.statsFn s.state))));
|
||||
IO.println (" number of imported entries: " ++ toString (s.importedEntries.foldl (λ sum es, sum + es.size) 0));
|
||||
IO.println (" number of imported entries: " ++ toString (s.importedEntries.foldl (fun sum es => sum + es.size) 0));
|
||||
pure ()
|
||||
};
|
||||
pure ()
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@ unsafe constant getConstTable : IO (Array (Name × NonScalar)) := default _
|
|||
See `src/init/init.cpp` -/
|
||||
@[export lean.sort_const_table_core]
|
||||
unsafe def sortConstTable : IO Unit :=
|
||||
modifyConstTable (λ cs, cs.qsort (λ e₁ e₂, Name.quickLt e₁.1 e₂.1))
|
||||
modifyConstTable (fun cs => cs.qsort (fun e₁ e₂ => Name.quickLt e₁.1 e₂.1))
|
||||
|
||||
/- We make this primitive as `unsafe` because it uses `unsafeCast`, and
|
||||
the program may crash if the type provided by the user is incorrect.
|
||||
It also assumes there are no threads trying to update the table concurrently. -/
|
||||
unsafe def evalConst (α : Type) [Inhabited α] (c : Name) : IO α :=
|
||||
do cs ← getConstTable;
|
||||
match cs.binSearch (c, default _) (λ e₁ e₂, Name.quickLt e₁.1 e₂.1) with
|
||||
match cs.binSearch (c, default _) (fun e₁ e₂ => Name.quickLt e₁.1 e₂.1) with
|
||||
| some (_, v) := pure (unsafeCast v)
|
||||
| none := throw (IO.userError ("unknow constant '" ++ toString c ++ "'"))
|
||||
|
||||
|
|
|
|||
|
|
@ -159,17 +159,17 @@ instance listHasFormat {α : Type u} [HasFormat α] : HasFormat (List α) :=
|
|||
⟨List.format⟩
|
||||
|
||||
instance prodHasFormat {α : Type u} {β : Type v} [HasFormat α] [HasFormat β] : HasFormat (Prod α β) :=
|
||||
⟨λ ⟨a, b⟩, paren $ format a ++ "," ++ line ++ format b⟩
|
||||
⟨fun ⟨a, b⟩ => paren $ format a ++ "," ++ line ++ format b⟩
|
||||
|
||||
def Format.joinArraySep {α : Type u} [HasFormat α] (a : Array α) (sep : Format) : Format :=
|
||||
a.iterate nil (λ i a r, if i.val > 0 then r ++ sep ++ format a else r ++ format a)
|
||||
a.iterate nil (fun i a r => if i.val > 0 then r ++ sep ++ format a else r ++ format a)
|
||||
|
||||
instance natHasFormat : HasFormat Nat := ⟨λ n, toString n⟩
|
||||
instance uint16HasFormat : HasFormat UInt16 := ⟨λ n, toString n⟩
|
||||
instance uint32HasFormat : HasFormat UInt32 := ⟨λ n, toString n⟩
|
||||
instance uint64HasFormat : HasFormat UInt64 := ⟨λ n, toString n⟩
|
||||
instance usizeHasFormat : HasFormat USize := ⟨λ n, toString n⟩
|
||||
instance nameHasFormat : HasFormat Name := ⟨λ n, n.toString⟩
|
||||
instance natHasFormat : HasFormat Nat := ⟨fun n => toString n⟩
|
||||
instance uint16HasFormat : HasFormat UInt16 := ⟨fun n => toString n⟩
|
||||
instance uint32HasFormat : HasFormat UInt32 := ⟨fun n => toString n⟩
|
||||
instance uint64HasFormat : HasFormat UInt64 := ⟨fun n => toString n⟩
|
||||
instance usizeHasFormat : HasFormat USize := ⟨fun n => toString n⟩
|
||||
instance nameHasFormat : HasFormat Name := ⟨fun n => n.toString⟩
|
||||
|
||||
protected def Format.repr : Format → Format
|
||||
| nil := "Format.nil"
|
||||
|
|
|
|||
|
|
@ -119,19 +119,19 @@ export isKVMapVal (set)
|
|||
isKVMapVal.get m k defVal
|
||||
|
||||
instance boolVal : isKVMapVal Bool :=
|
||||
{ defVal := false, set := setBool, get := λ k n v, getBool k n v }
|
||||
{ defVal := false, set := setBool, get := fun k n v => getBool k n v }
|
||||
|
||||
instance natVal : isKVMapVal Nat :=
|
||||
{ defVal := 0, set := setNat, get := λ k n v, getNat k n v }
|
||||
{ defVal := 0, set := setNat, get := fun k n v => getNat k n v }
|
||||
|
||||
instance intVal : isKVMapVal Int :=
|
||||
{ defVal := 0, set := setInt, get := λ k n v, getInt k n v }
|
||||
{ defVal := 0, set := setInt, get := fun k n v => getInt k n v }
|
||||
|
||||
instance nameVal : isKVMapVal Name :=
|
||||
{ defVal := Name.anonymous, set := setName, get := λ k n v, getName k n v }
|
||||
{ defVal := Name.anonymous, set := setName, get := fun k n v => getName k n v }
|
||||
|
||||
instance stringVal : isKVMapVal String :=
|
||||
{ defVal := "", set := setString, get := λ k n v, getString k n v }
|
||||
{ defVal := "", set := setString, get := fun k n v => getString k n v }
|
||||
|
||||
end KVMap
|
||||
end Lean
|
||||
|
|
|
|||
|
|
@ -111,8 +111,8 @@ partial def Result.format : Result → Bool → Format
|
|||
| (Result.offset f (k+1)) r :=
|
||||
let f' := Result.format f false;
|
||||
parenIfFalse (f' ++ "+" ++ fmt (k+1)) r
|
||||
| (Result.maxNode fs) r := parenIfFalse (Format.group $ "max" ++ formatLst (λ r, Result.format r false) fs) r
|
||||
| (Result.imaxNode fs) r := parenIfFalse (Format.group $ "imax" ++ formatLst (λ r, Result.format r false) fs) r
|
||||
| (Result.maxNode fs) r := parenIfFalse (Format.group $ "max" ++ formatLst (fun r => Result.format r false) fs) r
|
||||
| (Result.imaxNode fs) r := parenIfFalse (Format.group $ "imax" ++ formatLst (fun r => Result.format r false) fs) r
|
||||
|
||||
def Level.toResult : Level → Result
|
||||
| Level.zero := Result.num 0
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ instance : HasAppend MessageLog :=
|
|||
⟨MessageLog.append⟩
|
||||
|
||||
def hasErrors (log : MessageLog) : Bool :=
|
||||
log.revList.any $ λ m, match m.severity with
|
||||
log.revList.any $ fun m => match m.severity with
|
||||
| MessageSeverity.error := true
|
||||
| _ := false
|
||||
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ namespace Lean
|
|||
def mkProtectedExtension : IO (SimplePersistentEnvExtension Name NameSet) :=
|
||||
registerSimplePersistentEnvExtension {
|
||||
name := `protected,
|
||||
addImportedFn := λ as, {},
|
||||
addEntryFn := λ s n, s.insert n,
|
||||
toArrayFn := λ es, es.toArray.qsort Name.quickLt
|
||||
addImportedFn := fun as => {},
|
||||
addEntryFn := fun s n => s.insert n,
|
||||
toArrayFn := fun es => es.toArray.qsort Name.quickLt
|
||||
}
|
||||
|
||||
@[init mkProtectedExtension]
|
||||
|
|
|
|||
|
|
@ -63,20 +63,20 @@ protected def decEq : Π (a b : @& Name), Decidable (a = b)
|
|||
if h₁ : s₁ = s₂ then
|
||||
match decEq p₁ p₂ with
|
||||
| isTrue h₂ := isTrue $ h₁ ▸ h₂ ▸ rfl
|
||||
| isFalse h₂ := isFalse $ λ h, Name.noConfusion h $ λ hp hs, absurd hp h₂
|
||||
else isFalse $ λ h, Name.noConfusion h $ λ hp hs, absurd hs h₁
|
||||
| isFalse h₂ := isFalse $ fun h => Name.noConfusion h $ fun hp hs => absurd hp h₂
|
||||
else isFalse $ fun h => Name.noConfusion h $ fun hp hs => absurd hs h₁
|
||||
| (mkNumeral p₁ n₁) (mkNumeral p₂ n₂) :=
|
||||
if h₁ : n₁ = n₂ then
|
||||
match decEq p₁ p₂ with
|
||||
| isTrue h₂ := isTrue $ h₁ ▸ h₂ ▸ rfl
|
||||
| isFalse h₂ := isFalse $ λ h, Name.noConfusion h $ λ hp hs, absurd hp h₂
|
||||
else isFalse $ λ h, Name.noConfusion h $ λ hp hs, absurd hs h₁
|
||||
| anonymous (mkString _ _) := isFalse $ λ h, Name.noConfusion h
|
||||
| anonymous (mkNumeral _ _) := isFalse $ λ h, Name.noConfusion h
|
||||
| (mkString _ _) anonymous := isFalse $ λ h, Name.noConfusion h
|
||||
| (mkString _ _) (mkNumeral _ _) := isFalse $ λ h, Name.noConfusion h
|
||||
| (mkNumeral _ _) anonymous := isFalse $ λ h, Name.noConfusion h
|
||||
| (mkNumeral _ _) (mkString _ _) := isFalse $ λ h, Name.noConfusion h
|
||||
| isFalse h₂ := isFalse $ fun h => Name.noConfusion h $ fun hp hs => absurd hp h₂
|
||||
else isFalse $ fun h => Name.noConfusion h $ fun hp hs => absurd hs h₁
|
||||
| anonymous (mkString _ _) := isFalse $ fun h => Name.noConfusion h
|
||||
| anonymous (mkNumeral _ _) := isFalse $ fun h => Name.noConfusion h
|
||||
| (mkString _ _) anonymous := isFalse $ fun h => Name.noConfusion h
|
||||
| (mkString _ _) (mkNumeral _ _) := isFalse $ fun h => Name.noConfusion h
|
||||
| (mkNumeral _ _) anonymous := isFalse $ fun h => Name.noConfusion h
|
||||
| (mkNumeral _ _) (mkString _ _) := isFalse $ fun h => Name.noConfusion h
|
||||
|
||||
instance : DecidableEq Name :=
|
||||
{decEq := Name.decEq}
|
||||
|
|
@ -125,10 +125,10 @@ else quickLtCore n₁ n₂
|
|||
|
||||
/- Alternative HasLt instance. -/
|
||||
@[inline] protected def hasLtQuick : HasLess Name :=
|
||||
⟨λ a b, Name.quickLt a b = true⟩
|
||||
⟨fun a b => Name.quickLt a b = true⟩
|
||||
|
||||
@[inline] instance : DecidableRel (@HasLess.Less Name Name.hasLtQuick) :=
|
||||
inferInstanceAs (DecidableRel (λ a b, Name.quickLt a b = true))
|
||||
inferInstanceAs (DecidableRel (fun a b => Name.quickLt a b = true))
|
||||
|
||||
def toStringWithSep (sep : String) : Name → String
|
||||
| anonymous := "[anonymous]"
|
||||
|
|
@ -159,16 +159,16 @@ def isInternal : Name → Bool
|
|||
| _ := false
|
||||
|
||||
theorem mkStringNeMkStringOfNePrefix {p₁ : Name} (s₁ : String) {p₂ : Name} (s₂ : String) : p₁ ≠ p₂ → mkString p₁ s₁ ≠ mkString p₂ s₂ :=
|
||||
λ h₁ h₂, Name.noConfusion h₂ (λ h _, absurd h h₁)
|
||||
fun h₁ h₂ => Name.noConfusion h₂ (fun h _ => absurd h h₁)
|
||||
|
||||
theorem mkStringNeMkStringOfNeString (p₁ : Name) {s₁ : String} (p₂ : Name) {s₂ : String} : s₁ ≠ s₂ → mkString p₁ s₁ ≠ mkString p₂ s₂ :=
|
||||
λ h₁ h₂, Name.noConfusion h₂ (λ _ h, absurd h h₁)
|
||||
fun h₁ h₂ => Name.noConfusion h₂ (fun _ h => absurd h h₁)
|
||||
|
||||
theorem mkNumeralNeMkNumeralOfNePrefix {p₁ : Name} (n₁ : Nat) {p₂ : Name} (n₂ : Nat) : p₁ ≠ p₂ → mkNumeral p₁ n₁ ≠ mkNumeral p₂ n₂ :=
|
||||
λ h₁ h₂, Name.noConfusion h₂ (λ h _, absurd h h₁)
|
||||
fun h₁ h₂ => Name.noConfusion h₂ (fun h _ => absurd h h₁)
|
||||
|
||||
theorem mkNumeralNeMkNumeralOfNeNumeral (p₁ : Name) {n₁ : Nat} (p₂ : Name) {n₂ : Nat} : n₁ ≠ n₂ → mkNumeral p₁ n₁ ≠ mkNumeral p₂ n₂ :=
|
||||
λ h₁ h₂, Name.noConfusion h₂ (λ _ h, absurd h h₁)
|
||||
fun h₁ h₂ => Name.noConfusion h₂ (fun _ h => absurd h h₁)
|
||||
|
||||
end Name
|
||||
|
||||
|
|
@ -212,4 +212,4 @@ open Lean
|
|||
|
||||
def String.toName (s : String) : Name :=
|
||||
let ps := s.split ".";
|
||||
ps.foldl (λ n p, Name.mkString n p.trim) Name.anonymous
|
||||
ps.foldl (fun n p => Name.mkString n p.trim) Name.anonymous
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ constant builtinLevelParsingTable : IO.Ref ParsingTables := default _
|
|||
registerBuiltinParserAttribute `builtinLevelParser `Lean.Parser.builtinLevelParsingTable
|
||||
|
||||
def levelParser {k : ParserKind} (rbp : Nat := 0) : Parser k :=
|
||||
{ fn := λ _, runBuiltinParser "universe level" builtinLevelParsingTable rbp }
|
||||
{ fn := fun _ => runBuiltinParser "universe level" builtinLevelParsingTable rbp }
|
||||
|
||||
namespace Level
|
||||
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ def BasicParserFn := ParserContext → ParserState → ParserState
|
|||
|
||||
def ParserFn (k : ParserKind) := ParserArg k → BasicParserFn
|
||||
|
||||
instance ParserFn.inhabited (k : ParserKind) : Inhabited (ParserFn k) := ⟨λ _ _, id⟩
|
||||
instance ParserFn.inhabited (k : ParserKind) : Inhabited (ParserFn k) := ⟨fun _ _ => id⟩
|
||||
|
||||
inductive FirstTokens
|
||||
| epsilon : FirstTokens
|
||||
|
|
@ -168,7 +168,7 @@ instance : HasToString FirstTokens := ⟨toStr⟩
|
|||
end FirstTokens
|
||||
|
||||
structure ParserInfo :=
|
||||
(updateTokens : Trie TokenConfig → ExceptT String Id (Trie TokenConfig) := λ tks, pure tks)
|
||||
(updateTokens : Trie TokenConfig → ExceptT String Id (Trie TokenConfig) := fun tks => pure tks)
|
||||
(firstTokens : FirstTokens := FirstTokens.unknown)
|
||||
|
||||
structure Parser (k : ParserKind := leading) :=
|
||||
|
|
@ -176,7 +176,7 @@ structure Parser (k : ParserKind := leading) :=
|
|||
(fn : ParserFn k)
|
||||
|
||||
instance Parser.inhabited {k : ParserKind} : Inhabited (Parser k) :=
|
||||
⟨{ fn := λ _ _ s, s }⟩
|
||||
⟨{ fn := fun _ _ s => s }⟩
|
||||
|
||||
abbrev TrailingParser := Parser trailing
|
||||
|
||||
|
|
@ -184,14 +184,14 @@ abbrev TrailingParser := Parser trailing
|
|||
{ firstTokens := FirstTokens.epsilon }
|
||||
|
||||
@[inline] def pushLeadingFn : ParserFn trailing :=
|
||||
λ a c s, s.pushSyntax a
|
||||
fun a c s => s.pushSyntax a
|
||||
|
||||
@[inline] def pushLeading : TrailingParser :=
|
||||
{ info := epsilonInfo,
|
||||
fn := pushLeadingFn }
|
||||
|
||||
@[inline] def checkLeadingFn (p : Syntax → Bool) : ParserFn trailing :=
|
||||
λ a c s,
|
||||
fun a c s =>
|
||||
if p a then s
|
||||
else s.mkError "invalid leading token"
|
||||
|
||||
|
|
@ -200,15 +200,15 @@ abbrev TrailingParser := Parser trailing
|
|||
fn := checkLeadingFn p }
|
||||
|
||||
@[inline] def andthenAux (p q : BasicParserFn) : BasicParserFn :=
|
||||
λ c s,
|
||||
fun c s =>
|
||||
let s := p c s;
|
||||
if s.hasError then s else q c s
|
||||
|
||||
@[inline] def andthenFn {k : ParserKind} (p q : ParserFn k) : ParserFn k :=
|
||||
λ a c s, andthenAux (p a) (q a) c s
|
||||
fun a c s => andthenAux (p a) (q a) c s
|
||||
|
||||
@[noinline] def andthenInfo (p q : ParserInfo) : ParserInfo :=
|
||||
{ updateTokens := λ tks, q.updateTokens tks >>= p.updateTokens,
|
||||
{ updateTokens := fun tks => q.updateTokens tks >>= p.updateTokens,
|
||||
firstTokens := p.firstTokens.seq q.firstTokens }
|
||||
|
||||
@[inline] def andthen {k : ParserKind} (p q : Parser k) : Parser k :=
|
||||
|
|
@ -246,7 +246,7 @@ node n p
|
|||
if s.hasError && s.pos == iniPos then q a c (s.restore iniSz iniPos) else s
|
||||
|
||||
@[noinline] def orelseInfo (p q : ParserInfo) : ParserInfo :=
|
||||
{ updateTokens := λ tks, q.updateTokens tks >>= p.updateTokens,
|
||||
{ updateTokens := fun tks => q.updateTokens tks >>= p.updateTokens,
|
||||
firstTokens := p.firstTokens.merge q.firstTokens }
|
||||
|
||||
@[inline] def orelse {k : ParserKind} (p q : Parser k) : Parser k :=
|
||||
|
|
@ -272,7 +272,7 @@ instance hashOrelse {k : ParserKind} : HasOrelse (Parser k) :=
|
|||
fn := tryFn p.fn }
|
||||
|
||||
@[inline] def optionalFn {k : ParserKind} (p : ParserFn k) : ParserFn k :=
|
||||
λ a c s,
|
||||
fun a c s =>
|
||||
let iniSz := s.stackSize;
|
||||
let iniPos := s.pos;
|
||||
let s := p a c s;
|
||||
|
|
@ -293,7 +293,7 @@ instance hashOrelse {k : ParserKind} : HasOrelse (Parser k) :=
|
|||
else manyAux a c s
|
||||
|
||||
@[inline] def manyFn {k : ParserKind} (p : ParserFn k) : ParserFn k :=
|
||||
λ a c s,
|
||||
fun a c s =>
|
||||
let iniSz := s.stackSize;
|
||||
let s := manyAux p a c s;
|
||||
s.mkNode nullKind iniSz
|
||||
|
|
@ -303,7 +303,7 @@ instance hashOrelse {k : ParserKind} : HasOrelse (Parser k) :=
|
|||
fn := manyFn p.fn }
|
||||
|
||||
@[inline] def many1Fn {k : ParserKind} (p : ParserFn k) : ParserFn k :=
|
||||
λ a c s,
|
||||
fun a c s =>
|
||||
let iniSz := s.stackSize;
|
||||
let s := andthenFn p (manyAux p) a c s;
|
||||
s.mkNode nullKind iniSz
|
||||
|
|
@ -346,10 +346,10 @@ instance hashOrelse {k : ParserKind} : HasOrelse (Parser k) :=
|
|||
sepByFnAux p sep allowTrailingSep iniSz false a c s
|
||||
|
||||
@[noinline] def sepByInfo (p sep : ParserInfo) : ParserInfo :=
|
||||
{ updateTokens := λ tks, p.updateTokens tks >>= sep.updateTokens }
|
||||
{ updateTokens := fun tks => p.updateTokens tks >>= sep.updateTokens }
|
||||
|
||||
@[noinline] def sepBy1Info (p sep : ParserInfo) : ParserInfo :=
|
||||
{ updateTokens := λ tks, p.updateTokens tks >>= sep.updateTokens,
|
||||
{ updateTokens := fun tks => p.updateTokens tks >>= sep.updateTokens,
|
||||
firstTokens := p.firstTokens }
|
||||
|
||||
@[inline] def sepBy {k : ParserKind} (p sep : Parser k) (allowTrailingSep : Bool := false) : Parser k :=
|
||||
|
|
@ -375,7 +375,7 @@ instance hashOrelse {k : ParserKind} : HasOrelse (Parser k) :=
|
|||
else takeUntilFn c (s.next c.input i)
|
||||
|
||||
@[specialize] def takeWhileFn (p : Char → Bool) : BasicParserFn :=
|
||||
takeUntilFn (λ c, !p c)
|
||||
takeUntilFn (fun c => !p c)
|
||||
|
||||
@[inline] def takeWhile1Fn (p : Char → Bool) (errorMsg : String) : BasicParserFn :=
|
||||
andthenAux (satisfyFn p errorMsg) (takeWhileFn p)
|
||||
|
|
@ -417,7 +417,7 @@ partial def whitespace : BasicParserFn
|
|||
else if curr == '-' then
|
||||
let i := input.next i;
|
||||
let curr := input.get i;
|
||||
if curr == '-' then andthenAux (takeUntilFn (λ c, c = '\n')) whitespace c (s.next input i)
|
||||
if curr == '-' then andthenAux (takeUntilFn (fun c => c = '\n')) whitespace c (s.next input i)
|
||||
else s
|
||||
else if curr == '/' then
|
||||
let i := input.next i;
|
||||
|
|
@ -486,7 +486,7 @@ def quotedCharFn : BasicParserFn
|
|||
|
||||
/-- Push `(Syntax.node tk <new-atom>)` into syntax stack -/
|
||||
def mkNodeToken (n : SyntaxNodeKind) (startPos : Nat) : BasicParserFn :=
|
||||
λ c s,
|
||||
fun c s =>
|
||||
let input := c.input;
|
||||
let stopPos := s.pos;
|
||||
let leading := mkEmptySubstringAt input startPos;
|
||||
|
|
@ -511,8 +511,8 @@ partial def strLitFnAux (startPos : Nat) : BasicParserFn
|
|||
else strLitFnAux c s
|
||||
|
||||
def decimalNumberFn (startPos : Nat) : BasicParserFn :=
|
||||
λ c s,
|
||||
let s := takeWhileFn (λ c, c.isDigit) c s;
|
||||
fun c s =>
|
||||
let s := takeWhileFn (fun c => c.isDigit) c s;
|
||||
let input := c.input;
|
||||
let i := s.pos;
|
||||
let curr := input.get i;
|
||||
|
|
@ -522,28 +522,28 @@ def decimalNumberFn (startPos : Nat) : BasicParserFn :=
|
|||
let i := input.next i;
|
||||
let curr := input.get i;
|
||||
if curr.isDigit then
|
||||
takeWhileFn (λ c, c.isDigit) c (s.setPos i)
|
||||
takeWhileFn (fun c => c.isDigit) c (s.setPos i)
|
||||
else s
|
||||
else s;
|
||||
mkNodeToken numLitKind startPos c s
|
||||
|
||||
def binNumberFn (startPos : Nat) : BasicParserFn :=
|
||||
λ c s,
|
||||
let s := takeWhile1Fn (λ c, c == '0' || c == '1') "expected binary number" c s;
|
||||
fun c s =>
|
||||
let s := takeWhile1Fn (fun c => c == '0' || c == '1') "expected binary number" c s;
|
||||
mkNodeToken numLitKind startPos c s
|
||||
|
||||
def octalNumberFn (startPos : Nat) : BasicParserFn :=
|
||||
λ c s,
|
||||
let s := takeWhile1Fn (λ c, '0' ≤ c && c ≤ '7') "expected octal number" c s;
|
||||
fun c s =>
|
||||
let s := takeWhile1Fn (fun c => '0' ≤ c && c ≤ '7') "expected octal number" c s;
|
||||
mkNodeToken numLitKind startPos c s
|
||||
|
||||
def hexNumberFn (startPos : Nat) : BasicParserFn :=
|
||||
λ c s,
|
||||
let s := takeWhile1Fn (λ c, ('0' ≤ c && c ≤ '9') || ('a' ≤ c && c ≤ 'f') || ('A' ≤ c && c ≤ 'F')) "expected hexadecimal number" c s;
|
||||
fun c s =>
|
||||
let s := takeWhile1Fn (fun c => ('0' ≤ c && c ≤ '9') || ('a' ≤ c && c ≤ 'f') || ('A' ≤ c && c ≤ 'F')) "expected hexadecimal number" c s;
|
||||
mkNodeToken numLitKind startPos c s
|
||||
|
||||
def numberFnAux : BasicParserFn :=
|
||||
λ c s,
|
||||
fun c s =>
|
||||
let input := c.input;
|
||||
let startPos := s.pos;
|
||||
if input.atEnd startPos then s.mkEOIError
|
||||
|
|
@ -588,7 +588,7 @@ match tk with
|
|||
tk.val.bsize ≥ idStopPos - idStopPos
|
||||
|
||||
def mkTokenAndFixPos (startPos : Nat) (tk : Option TokenConfig) : BasicParserFn :=
|
||||
λ c s,
|
||||
fun c s =>
|
||||
match tk with
|
||||
| none := s.mkErrorAt "token expected" startPos
|
||||
| some tk :=
|
||||
|
|
@ -604,7 +604,7 @@ match tk with
|
|||
s.pushSyntax atom
|
||||
|
||||
def mkIdResult (startPos : Nat) (tk : Option TokenConfig) (val : Name) : BasicParserFn :=
|
||||
λ c s,
|
||||
fun c s =>
|
||||
let stopPos := s.pos;
|
||||
if isToken startPos stopPos tk then
|
||||
mkTokenAndFixPos startPos tk c s
|
||||
|
|
@ -673,7 +673,7 @@ match s with
|
|||
| other := other
|
||||
|
||||
def tokenFn : BasicParserFn :=
|
||||
λ c s,
|
||||
fun c s =>
|
||||
let input := c.input;
|
||||
let i := s.pos;
|
||||
if input.atEnd i then s.mkEOIError
|
||||
|
|
@ -696,7 +696,7 @@ else
|
|||
(s.restore iniSz iniPos, some stx)
|
||||
|
||||
@[inline] def satisfySymbolFn (p : String → Bool) (errorMsg : String) : BasicParserFn :=
|
||||
λ c s,
|
||||
fun c s =>
|
||||
let startPos := s.pos;
|
||||
let s := tokenFn c s;
|
||||
if s.hasError then
|
||||
|
|
@ -707,7 +707,7 @@ else
|
|||
| _ := s.mkErrorAt errorMsg startPos
|
||||
|
||||
def symbolFnAux (sym : String) (errorMsg : String) : BasicParserFn :=
|
||||
satisfySymbolFn (λ s, s == sym) errorMsg
|
||||
satisfySymbolFn (fun s => s == sym) errorMsg
|
||||
|
||||
def insertToken (sym : String) (lbp : Option Nat) (tks : Trie TokenConfig) : ExceptT String Id (Trie TokenConfig) :=
|
||||
match tks.find sym, lbp with
|
||||
|
|
@ -723,7 +723,7 @@ def symbolInfo (sym : String) (lbp : Option Nat) : ParserInfo :=
|
|||
firstTokens := FirstTokens.tokens [ { val := sym, lbp := lbp } ] }
|
||||
|
||||
@[inline] def symbolFn {k : ParserKind} (sym : String) : ParserFn k :=
|
||||
λ _, symbolFnAux sym ("expected '" ++ sym ++ "'")
|
||||
fun _ => symbolFnAux sym ("expected '" ++ sym ++ "'")
|
||||
|
||||
@[inline] def symbol {k : ParserKind} (sym : String) (lbp : Option Nat := none) : Parser k :=
|
||||
let sym := sym.trim;
|
||||
|
|
@ -731,14 +731,14 @@ let sym := sym.trim;
|
|||
fn := symbolFn sym }
|
||||
|
||||
def unicodeSymbolFnAux (sym asciiSym : String) (errorMsg : String) : BasicParserFn :=
|
||||
satisfySymbolFn (λ s, s == sym || s == asciiSym) errorMsg
|
||||
satisfySymbolFn (fun s => s == sym || s == asciiSym) errorMsg
|
||||
|
||||
def unicodeSymbolInfo (sym asciiSym : String) (lbp : Option Nat) : ParserInfo :=
|
||||
{ updateTokens := λ tks, insertToken sym lbp tks >>= insertToken asciiSym lbp,
|
||||
{ updateTokens := fun tks => insertToken sym lbp tks >>= insertToken asciiSym lbp,
|
||||
firstTokens := FirstTokens.tokens [ { val := sym, lbp := lbp }, { val := asciiSym, lbp := lbp } ] }
|
||||
|
||||
@[inline] def unicodeSymbolFn {k : ParserKind} (sym asciiSym : String) : ParserFn k :=
|
||||
λ _, unicodeSymbolFnAux sym asciiSym ("expected '" ++ sym ++ "' or '" ++ asciiSym ++ "'")
|
||||
fun _ => unicodeSymbolFnAux sym asciiSym ("expected '" ++ sym ++ "' or '" ++ asciiSym ++ "'")
|
||||
|
||||
@[inline] def unicodeSymbol {k : ParserKind} (sym asciiSym : String) (lbp : Option Nat := none) : Parser k :=
|
||||
{ info := unicodeSymbolInfo sym asciiSym lbp,
|
||||
|
|
@ -748,7 +748,7 @@ def mkAtomicInfo (k : String) : ParserInfo :=
|
|||
{ firstTokens := FirstTokens.tokens [ { val := k } ] }
|
||||
|
||||
def numLitFn {k : ParserKind} : ParserFn k :=
|
||||
λ _ c s,
|
||||
fun _ c s =>
|
||||
let s := tokenFn c s;
|
||||
if s.hasError || !(s.stxStack.back.isOfKind numLitKind) then s.mkError "expected numeral" else s
|
||||
|
||||
|
|
@ -757,7 +757,7 @@ def numLitFn {k : ParserKind} : ParserFn k :=
|
|||
info := mkAtomicInfo "numLit" }
|
||||
|
||||
def strLitFn {k : ParserKind} : ParserFn k :=
|
||||
λ _ c s,
|
||||
fun _ c s =>
|
||||
let s := tokenFn c s;
|
||||
if s.hasError || !(s.stxStack.back.isOfKind strLitKind) then s.mkError "expected string literal" else s
|
||||
|
||||
|
|
@ -766,7 +766,7 @@ if s.hasError || !(s.stxStack.back.isOfKind strLitKind) then s.mkError "expected
|
|||
info := mkAtomicInfo "strLit" }
|
||||
|
||||
def identFn {k : ParserKind} : ParserFn k :=
|
||||
λ _ c s,
|
||||
fun _ c s =>
|
||||
let s := tokenFn c s;
|
||||
if s.hasError || !(s.stxStack.back.isIdent) then
|
||||
s.mkError "expected identifier"
|
||||
|
|
@ -821,7 +821,7 @@ s.keepLatest startStackSize
|
|||
end ParserState
|
||||
|
||||
def longestMatchStep {k : ParserKind} (startSize : Nat) (startPos : String.Pos) (p : ParserFn k) : ParserFn k :=
|
||||
λ a c s,
|
||||
fun a c s =>
|
||||
let prevErrorMsg := s.errorMsg;
|
||||
let prevStopPos := s.pos;
|
||||
let prevSize := s.stackSize;
|
||||
|
|
@ -845,21 +845,21 @@ def longestMatchMkResult (startSize : Nat) (s : ParserState) : ParserState :=
|
|||
if !s.hasError && s.stackSize > startSize + 1 then s.mkNode choiceKind startSize else s
|
||||
|
||||
def longestMatchFnAux {k : ParserKind} (startSize : Nat) (startPos : String.Pos) : List (Parser k) → ParserFn k
|
||||
| [] := λ _ _ s, longestMatchMkResult startSize s
|
||||
| (p::ps) := λ a c s,
|
||||
| [] := fun _ _ s => longestMatchMkResult startSize s
|
||||
| (p::ps) := fun a c s =>
|
||||
let s := longestMatchStep startSize startPos p.fn a c s;
|
||||
longestMatchFnAux ps a c s
|
||||
|
||||
def longestMatchFn₁ {k : ParserKind} (p : ParserFn k) : ParserFn k :=
|
||||
λ a c s,
|
||||
fun a c s =>
|
||||
let startSize := s.stackSize;
|
||||
let s := p a c s;
|
||||
if s.hasError then s else s.mkLongestNodeAlt startSize
|
||||
|
||||
def longestMatchFn {k : ParserKind} : List (Parser k) → ParserFn k
|
||||
| [] := λ _ _ s, s.mkError "longestMatch: empty list"
|
||||
| [] := fun _ _ s => s.mkError "longestMatch: empty list"
|
||||
| [p] := longestMatchFn₁ p.fn
|
||||
| (p::ps) := λ a c s,
|
||||
| (p::ps) := fun a c s =>
|
||||
let startSize := s.stackSize;
|
||||
let startPos := s.pos;
|
||||
let s := p.fn a c s;
|
||||
|
|
@ -925,7 +925,7 @@ if s.stackSize == iniSz + 1 then s
|
|||
else s.mkNode nullKind iniSz -- throw error instead?
|
||||
|
||||
def leadingParser (kind : String) (tables : ParsingTables) : ParserFn leading :=
|
||||
λ a c s,
|
||||
fun a c s =>
|
||||
let iniSz := s.stackSize;
|
||||
let (s, ps) := indexed tables.leadingTable c s;
|
||||
if ps.isEmpty then
|
||||
|
|
@ -953,7 +953,7 @@ partial def trailingLoop (kind : String) (tables : ParsingTables) (rbp : Nat) (c
|
|||
trailingLoop left s
|
||||
|
||||
def prattParser (kind : String) (tables : ParsingTables) : ParserFn leading :=
|
||||
λ rbp c s,
|
||||
fun rbp c s =>
|
||||
let c := { tokens := tables.tokens, .. c };
|
||||
let s := leadingParser kind tables rbp c s;
|
||||
if s.hasError then s
|
||||
|
|
@ -995,7 +995,7 @@ do tables ← tablesRef.get;
|
|||
tables ← updateTokens tables p.info;
|
||||
match p.info.firstTokens with
|
||||
| FirstTokens.tokens tks :=
|
||||
let tables := tks.foldl (λ (tables : ParsingTables) tk, { leadingTable := tables.leadingTable.insert (mkSimpleName tk.val) p, .. tables }) tables;
|
||||
let tables := tks.foldl (fun (tables : ParsingTables) tk => { leadingTable := tables.leadingTable.insert (mkSimpleName tk.val) p, .. tables }) tables;
|
||||
tablesRef.set tables
|
||||
| _ :=
|
||||
throw (IO.userError ("invalid builtin parser '" ++ toString declName ++ "', initial token is not statically known"))
|
||||
|
|
@ -1006,7 +1006,7 @@ do tables ← tablesRef.get;
|
|||
tables ← updateTokens tables p.info;
|
||||
match p.info.firstTokens with
|
||||
| FirstTokens.tokens tks :=
|
||||
let tables := tks.foldl (λ (tables : ParsingTables) tk, { trailingTable := tables.trailingTable.insert (mkSimpleName tk.val) p, .. tables }) tables;
|
||||
let tables := tks.foldl (fun (tables : ParsingTables) tk => { trailingTable := tables.trailingTable.insert (mkSimpleName tk.val) p, .. tables }) tables;
|
||||
tablesRef.set tables
|
||||
| _ :=
|
||||
let tables := { trailingParsers := p :: tables.trailingParsers, .. tables };
|
||||
|
|
@ -1034,7 +1034,7 @@ def registerBuiltinParserAttribute (attrName : Name) (refDeclName : Name) : IO U
|
|||
registerAttribute {
|
||||
name := attrName,
|
||||
descr := "Builtin parser",
|
||||
add := λ env declName args persistent, do {
|
||||
add := fun env declName args persistent => do {
|
||||
unless args.isMissing $ throw (IO.userError ("invalid attribute '" ++ toString attrName ++ "', unexpected argument"));
|
||||
unless persistent $ throw (IO.userError ("invalid attribute '" ++ toString attrName ++ "', must be persistent"));
|
||||
match env.find declName with
|
||||
|
|
@ -1058,7 +1058,7 @@ constant builtinCommandParsingTable : IO.Ref ParsingTables := default _
|
|||
registerBuiltinParserAttribute `builtinCommandParser `Lean.Parser.builtinCommandParsingTable
|
||||
|
||||
@[noinline] unsafe def runBuiltinParserUnsafe (kind : String) (ref : IO.Ref ParsingTables) : ParserFn leading :=
|
||||
λ a c s,
|
||||
fun a c s =>
|
||||
match unsafeIO (do tables ← ref.get; pure $ prattParser kind tables a c s) with
|
||||
| some s := s
|
||||
| none := s.mkError "failed to access builtin reference"
|
||||
|
|
@ -1067,7 +1067,7 @@ match unsafeIO (do tables ← ref.get; pure $ prattParser kind tables a c s) wit
|
|||
constant runBuiltinParser (kind : String) (ref : IO.Ref ParsingTables) : ParserFn leading := default _
|
||||
|
||||
def commandParser (rbp : Nat := 0) : Parser :=
|
||||
{ fn := λ _, runBuiltinParser "command" builtinCommandParsingTable rbp }
|
||||
{ fn := fun _ => runBuiltinParser "command" builtinCommandParsingTable rbp }
|
||||
|
||||
/- TODO(Leo): delete -/
|
||||
@[init mkBuiltinParsingTablesRef]
|
||||
|
|
@ -1076,7 +1076,7 @@ constant builtinTestParsingTable : IO.Ref ParsingTables := default _
|
|||
registerBuiltinParserAttribute `builtinTestParser `Lean.Parser.builtinTestParsingTable
|
||||
|
||||
def testParser (rbp : Nat := 0) : Parser :=
|
||||
{ fn := λ _, runBuiltinParser "testExpr" builtinTestParsingTable rbp }
|
||||
{ fn := fun _ => runBuiltinParser "testExpr" builtinTestParsingTable rbp }
|
||||
|
||||
end Parser
|
||||
end Lean
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ constant builtinTermParsingTable : IO.Ref ParsingTables := default _
|
|||
registerBuiltinParserAttribute `builtinTermParser `Lean.Parser.builtinTermParsingTable
|
||||
|
||||
def termParser {k : ParserKind} (rbp : Nat := 0) : Parser k :=
|
||||
{ fn := λ _, runBuiltinParser "term" builtinTermParsingTable rbp }
|
||||
{ fn := fun _ => runBuiltinParser "term" builtinTermParsingTable rbp }
|
||||
|
||||
namespace Term
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Lean
|
|||
namespace Parser
|
||||
|
||||
inductive Trie (α : Type)
|
||||
| Node : Option α → RBNode Char (λ _, Trie) → Trie
|
||||
| Node : Option α → RBNode Char (fun _ => Trie) → Trie
|
||||
|
||||
namespace Trie
|
||||
variables {α : Type}
|
||||
|
|
@ -85,11 +85,11 @@ def matchPrefix (s : String) (t : Trie α) (i : String.Pos) : String.Pos × Opti
|
|||
matchPrefixAux s t i (i, none)
|
||||
|
||||
private partial def toStringAux {α : Type} : Trie α → List Format
|
||||
| (Trie.Node val map) := map.fold (λ Fs c t,
|
||||
| (Trie.Node val map) := map.fold (fun Fs c t =>
|
||||
format (repr c) :: (Format.group $ Format.nest 2 $ flip Format.joinSep Format.line $ toStringAux t) :: Fs) []
|
||||
|
||||
instance {α : Type} : HasToString (Trie α) :=
|
||||
⟨λ t, (flip Format.joinSep Format.line $ toStringAux t).pretty⟩
|
||||
⟨fun t => (flip Format.joinSep Format.line $ toStringAux t).pretty⟩
|
||||
end Trie
|
||||
|
||||
end Parser
|
||||
|
|
|
|||
|
|
@ -14,17 +14,17 @@ structure Position :=
|
|||
|
||||
namespace Position
|
||||
instance : DecidableEq Position :=
|
||||
{decEq := λ ⟨l₁, c₁⟩ ⟨l₂, c₂⟩,
|
||||
{decEq := fun ⟨l₁, c₁⟩ ⟨l₂, c₂⟩ =>
|
||||
if h₁ : l₁ = l₂ then
|
||||
if h₂ : c₁ = c₂ then isTrue (Eq.recOn h₁ (Eq.recOn h₂ rfl))
|
||||
else isFalse (λ contra, Position.noConfusion contra (λ e₁ e₂, absurd e₂ h₂))
|
||||
else isFalse (λ contra, Position.noConfusion contra (λ e₁ e₂, absurd e₁ h₁))}
|
||||
else isFalse (fun contra => Position.noConfusion contra (fun e₁ e₂ => absurd e₂ h₂))
|
||||
else isFalse (fun contra => Position.noConfusion contra (fun e₁ e₂ => absurd e₁ h₁))}
|
||||
|
||||
protected def lt : Position → Position → Bool
|
||||
| ⟨l₁, c₁⟩ ⟨l₂, c₂⟩ := (l₁, c₁) < (l₂, c₂)
|
||||
|
||||
instance : HasFormat Position :=
|
||||
⟨λ ⟨l, c⟩, "⟨" ++ fmt l ++ ", " ++ fmt c ++ "⟩"⟩
|
||||
⟨fun ⟨l, c⟩ => "⟨" ++ fmt l ++ ", " ++ fmt c ++ "⟩"⟩
|
||||
|
||||
instance : Inhabited Position := ⟨⟨1, 0⟩⟩
|
||||
end Position
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ instance ProjectionFunctionInfo.inhabited : Inhabited ProjectionFunctionInfo :=
|
|||
def mkProjectionFnInfoExtension : IO (SimplePersistentEnvExtension (Name × ProjectionFunctionInfo) (NameMap ProjectionFunctionInfo)) :=
|
||||
registerSimplePersistentEnvExtension {
|
||||
name := `projinfo,
|
||||
addImportedFn := λ as, {},
|
||||
addEntryFn := λ s p, s.insert p.1 p.2,
|
||||
toArrayFn := λ es, es.toArray.qsort (λ a b, Name.quickLt a.1 b.1)
|
||||
addImportedFn := fun as => {},
|
||||
addEntryFn := fun s p => s.insert p.1 p.2,
|
||||
toArrayFn := fun es => es.toArray.qsort (fun a b => Name.quickLt a.1 b.1)
|
||||
}
|
||||
|
||||
@[init mkProjectionFnInfoExtension]
|
||||
|
|
@ -40,14 +40,14 @@ namespace Environment
|
|||
def getProjectionFnInfo (env : Environment) (projName : Name) : Option ProjectionFunctionInfo :=
|
||||
match env.getModuleIdxFor projName with
|
||||
| some modIdx :=
|
||||
match (projectionFnInfoExt.getModuleEntries env modIdx).binSearch (projName, default _) (λ a b, Name.quickLt a.1 b.1) with
|
||||
match (projectionFnInfoExt.getModuleEntries env modIdx).binSearch (projName, default _) (fun a b => Name.quickLt a.1 b.1) with
|
||||
| some e := some e.2
|
||||
| none := none
|
||||
| none := (projectionFnInfoExt.getState env).find projName
|
||||
|
||||
def isProjectionFn (env : Environment) (n : Name) : Bool :=
|
||||
match env.getModuleIdxFor n with
|
||||
| some modIdx := (projectionFnInfoExt.getModuleEntries env modIdx).binSearchContains (n, default _) (λ a b, Name.quickLt a.1 b.1)
|
||||
| some modIdx := (projectionFnInfoExt.getModuleEntries env modIdx).binSearchContains (n, default _) (fun a b => Name.quickLt a.1 b.1)
|
||||
| none := (projectionFnInfoExt.getState env).contains n
|
||||
|
||||
end Environment
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ private def updateLeadingAux : Syntax → State String.Pos (Option Syntax)
|
|||
Note that, the `SourceInfo.trailing` fields are correct.
|
||||
The implementation of this Function relies on this property. -/
|
||||
def updateLeading : Syntax → Syntax :=
|
||||
λ stx, Prod.fst <$> (mreplace updateLeadingAux stx).run 0
|
||||
fun stx => Prod.fst <$> (mreplace updateLeadingAux stx).run 0
|
||||
|
||||
partial def updateTrailing (trailing : Substring) : Syntax → Syntax
|
||||
| (Syntax.atom (some info) val) := Syntax.atom (some (info.updateTrailing trailing)) val
|
||||
|
|
@ -185,8 +185,8 @@ partial def reprint : Syntax → Option String
|
|||
if args.size == 0 then failure
|
||||
else do
|
||||
s ← reprint (args.get 0);
|
||||
args.mfoldlFrom (λ s stx, do s' ← reprint stx; guard (s == s'); pure s) s 1
|
||||
else args.mfoldl (λ r stx, do s ← reprint stx; pure $ r ++ s) ""
|
||||
args.mfoldlFrom (fun s stx => do s' ← reprint stx; guard (s == s'); pure s) s 1
|
||||
else args.mfoldl (fun r stx => do s ← reprint stx; pure $ r ++ s) ""
|
||||
| missing := ""
|
||||
|
||||
open Lean.Format
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ export ToExpr (toExpr)
|
|||
|
||||
instance exprToExpr : ToExpr Expr := ⟨id⟩
|
||||
|
||||
instance natToExpr : ToExpr Nat := ⟨λ n, Expr.lit (Literal.natVal n)⟩
|
||||
instance natToExpr : ToExpr Nat := ⟨fun n => Expr.lit (Literal.natVal n)⟩
|
||||
|
||||
instance strToExpr : ToExpr String := ⟨λ s, Expr.lit (Literal.strVal s)⟩
|
||||
instance strToExpr : ToExpr String := ⟨fun s => Expr.lit (Literal.strVal s)⟩
|
||||
|
||||
def nameToExprAux : Name → Expr
|
||||
| Name.anonymous := mkConst `Lean.Name.anonymous
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ inductive Trace
|
|||
|
||||
partial def Trace.pp : Trace → Format
|
||||
| (Trace.mk (Message.fromFormat fmt) subtraces) :=
|
||||
fmt ++ Format.nest 2 (Format.join $ subtraces.map (λ t, Format.line ++ t.pp))
|
||||
fmt ++ Format.nest 2 (Format.join $ subtraces.map (fun t => Format.line ++ t.pp))
|
||||
|
||||
namespace Trace
|
||||
|
||||
|
|
@ -47,16 +47,16 @@ def Trace {m} [Monad m] [MonadTracer m] (cls : Name) (msg : Message) : m Unit :=
|
|||
traceCtx cls msg (pure () : m Unit)
|
||||
|
||||
instance (m) [Monad m] : MonadTracer (TraceT m) :=
|
||||
{ traceRoot := λ α pos cls msg ctx, do {
|
||||
{ traceRoot := fun α pos cls msg ctx => do {
|
||||
st ← get;
|
||||
if st.opts.getBool cls = true then do {
|
||||
modify $ λ st, {curPos := pos, curTraces := [], ..st};
|
||||
modify $ fun st => {curPos := pos, curTraces := [], ..st};
|
||||
a ← ctx.get;
|
||||
modify $ λ (st : TraceState), {roots := st.roots.insert pos ⟨msg, st.curTraces⟩, ..st};
|
||||
modify $ fun (st : TraceState) => {roots := st.roots.insert pos ⟨msg, st.curTraces⟩, ..st};
|
||||
pure a
|
||||
} else ctx.get
|
||||
},
|
||||
traceCtx := λ α cls msg ctx, do {
|
||||
traceCtx := fun α cls msg ctx => do {
|
||||
st ← get;
|
||||
-- tracing enabled?
|
||||
some _ ← pure st.curPos | ctx.get;
|
||||
|
|
@ -64,13 +64,13 @@ instance (m) [Monad m] : MonadTracer (TraceT m) :=
|
|||
if st.opts.getBool cls = true then do {
|
||||
set {curTraces := [], ..st};
|
||||
a ← ctx.get;
|
||||
modify $ λ (st' : TraceState), {curTraces := st.curTraces ++ [⟨msg, st'.curTraces⟩], ..st'};
|
||||
modify $ fun (st' : TraceState) => {curTraces := st.curTraces ++ [⟨msg, st'.curTraces⟩], ..st'};
|
||||
pure a
|
||||
} else
|
||||
-- disable tracing inside 'ctx'
|
||||
adaptState'
|
||||
(λ _, {curPos := none, ..st})
|
||||
(λ st', {curPos := st.curPos, ..st'})
|
||||
(fun _ => {curPos := none, ..st})
|
||||
(fun st' => {curPos := st.curPos, ..st'})
|
||||
ctx.get
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,20 +17,20 @@ inductive Acc {α : Sort u} (r : α → α → Prop) : α → Prop
|
|||
def Acc.ndrec.{u1, u2} {α : Sort u2} {r : α → α → Prop} {C : α → Sort u1}
|
||||
(m : Π (x : α) (h : ∀ (y : α), r y x → Acc r y), (Π (y : α) (a : r y x), C y) → C x)
|
||||
{a : α} (n : Acc r a) : C a :=
|
||||
@Acc.rec α r (λ α _, C α) m a n
|
||||
@Acc.rec α r (fun α _ => C α) m a n
|
||||
|
||||
@[elabAsEliminator, inline, reducible]
|
||||
def Acc.ndrecOn.{u1, u2} {α : Sort u2} {r : α → α → Prop} {C : α → Sort u1}
|
||||
{a : α} (n : Acc r a)
|
||||
(m : Π (x : α) (h : ∀ (y : α), r y x → Acc r y), (Π (y : α) (a : r y x), C y) → C x)
|
||||
: C a :=
|
||||
@Acc.rec α r (λ α _, C α) m a n
|
||||
@Acc.rec α r (fun α _ => C α) m a n
|
||||
|
||||
namespace Acc
|
||||
variables {α : Sort u} {r : α → α → Prop}
|
||||
|
||||
def inv {x y : α} (h₁ : Acc r x) (h₂ : r y x) : Acc r y :=
|
||||
Acc.recOn h₁ (λ x₁ ac₁ ih h₂, ac₁ y h₂) h₂
|
||||
Acc.recOn h₁ (fun x₁ ac₁ ih h₂ => ac₁ y h₂) h₂
|
||||
|
||||
end Acc
|
||||
|
||||
|
|
@ -42,13 +42,13 @@ class HasWellFounded (α : Sort u) : Type u :=
|
|||
|
||||
namespace WellFounded
|
||||
def apply {α : Sort u} {r : α → α → Prop} (wf : WellFounded r) : ∀ a, Acc r a :=
|
||||
λ a, WellFounded.recOn wf (λ p, p) a
|
||||
fun a => WellFounded.recOn wf (fun p => p) a
|
||||
|
||||
section
|
||||
variables {α : Sort u} {r : α → α → Prop} (hwf : WellFounded r)
|
||||
|
||||
theorem recursion {C : α → Sort v} (a : α) (h : Π x, (Π y, r y x → C y) → C x) : C a :=
|
||||
Acc.recOn (apply hwf a) (λ x₁ ac₁ ih, h x₁ ih)
|
||||
Acc.recOn (apply hwf a) (fun x₁ ac₁ ih => h x₁ ih)
|
||||
|
||||
theorem induction {C : α → Prop} (a : α) (h : ∀ x, (∀ y, r y x → C y) → C x) : C a :=
|
||||
recursion hwf a h
|
||||
|
|
@ -57,11 +57,11 @@ variable {C : α → Sort v}
|
|||
variable F : Π x, (Π y, r y x → C y) → C x
|
||||
|
||||
def fixF (x : α) (a : Acc r x) : C x :=
|
||||
Acc.recOn a (λ x₁ ac₁ ih, F x₁ ih)
|
||||
Acc.recOn a (fun x₁ ac₁ ih => F x₁ ih)
|
||||
|
||||
theorem fixFEq (x : α) (acx : Acc r x) :
|
||||
fixF F x acx = F x (λ (y : α) (p : r y x), fixF F y (Acc.inv acx p)) :=
|
||||
Acc.rec (λ x r ih, rfl) acx
|
||||
fixF F x acx = F x (fun (y : α) (p : r y x) => fixF F y (Acc.inv acx p)) :=
|
||||
Acc.rec (fun x r ih => rfl) acx
|
||||
end
|
||||
|
||||
variables {α : Sort u} {C : α → Sort v} {r : α → α → Prop}
|
||||
|
|
@ -72,7 +72,7 @@ fixF F x (apply hwf x)
|
|||
|
||||
-- Well-founded fixpoint satisfies fixpoint equation
|
||||
theorem fixEq (hwf : WellFounded r) (F : Π x, (Π y, r y x → C y) → C x) (x : α) :
|
||||
fix hwf F x = F x (λ y h, fix hwf F y) :=
|
||||
fix hwf F x = F x (fun y h => fix hwf F y) :=
|
||||
fixFEq F x (apply hwf x)
|
||||
end WellFounded
|
||||
|
||||
|
|
@ -80,19 +80,19 @@ open WellFounded
|
|||
|
||||
-- Empty relation is well-founded
|
||||
def emptyWf {α : Sort u} : WellFounded (@emptyRelation α) :=
|
||||
WellFounded.intro (λ (a : α),
|
||||
Acc.intro a (λ (b : α) (lt : False), False.rec _ lt))
|
||||
WellFounded.intro (fun (a : α) =>
|
||||
Acc.intro a (fun (b : α) (lt : False) => False.rec _ lt))
|
||||
|
||||
-- Subrelation of a well-founded relation is well-founded
|
||||
namespace Subrelation
|
||||
variables {α : Sort u} {r q : α → α → Prop}
|
||||
|
||||
def accessible {a : α} (h₁ : Subrelation q r) (ac : Acc r a) : Acc q a :=
|
||||
Acc.recOn ac $ λ x ax ih,
|
||||
Acc.intro x $ λ (y : α) (lt : q y x), ih y (h₁ lt)
|
||||
Acc.recOn ac $ fun x ax ih =>
|
||||
Acc.intro x $ fun (y : α) (lt : q y x) => ih y (h₁ lt)
|
||||
|
||||
def wf (h₁ : Subrelation q r) (h₂ : WellFounded r) : WellFounded q :=
|
||||
⟨λ a, accessible @h₁ (apply h₂ a)⟩
|
||||
⟨fun a => accessible @h₁ (apply h₂ a)⟩
|
||||
end Subrelation
|
||||
|
||||
-- The inverse image of a well-founded relation is well-founded
|
||||
|
|
@ -100,15 +100,15 @@ namespace InvImage
|
|||
variables {α : Sort u} {β : Sort v} {r : β → β → Prop}
|
||||
|
||||
private def accAux (f : α → β) {b : β} (ac : Acc r b) : ∀ (x : α), f x = b → Acc (InvImage r f) x :=
|
||||
Acc.ndrecOn ac $ λ x acx ih z e,
|
||||
Acc.intro z $ λ y lt,
|
||||
Eq.ndrecOn e (λ acx ih, ih (f y) lt y rfl) acx ih
|
||||
Acc.ndrecOn ac $ fun x acx ih z e =>
|
||||
Acc.intro z $ fun y lt =>
|
||||
Eq.ndrecOn e (fun acx ih => ih (f y) lt y rfl) acx ih
|
||||
|
||||
def accessible {a : α} (f : α → β) (ac : Acc r (f a)) : Acc (InvImage r f) a :=
|
||||
accAux f ac a rfl
|
||||
|
||||
def wf (f : α → β) (h : WellFounded r) : WellFounded (InvImage r f) :=
|
||||
⟨λ a, accessible f (apply h (f a))⟩
|
||||
⟨fun a => accessible f (apply h (f a))⟩
|
||||
end InvImage
|
||||
|
||||
-- The transitive closure of a well-founded relation is well-founded
|
||||
|
|
@ -116,27 +116,27 @@ namespace TC
|
|||
variables {α : Sort u} {r : α → α → Prop}
|
||||
|
||||
def accessible {z : α} (ac : Acc r z) : Acc (TC r) z :=
|
||||
Acc.ndrecOn ac $ λ x acx ih,
|
||||
Acc.intro x $ λ y rel,
|
||||
Acc.ndrecOn ac $ fun x acx ih =>
|
||||
Acc.intro x $ fun y rel =>
|
||||
TC.ndrecOn rel
|
||||
(λ a b rab acx ih, ih a rab)
|
||||
(λ a b c rab rbc ih₁ ih₂ acx ih, Acc.inv (ih₂ acx ih) rab)
|
||||
(fun a b rab acx ih => ih a rab)
|
||||
(fun a b c rab rbc ih₁ ih₂ acx ih => Acc.inv (ih₂ acx ih) rab)
|
||||
acx ih
|
||||
|
||||
def wf (h : WellFounded r) : WellFounded (TC r) :=
|
||||
⟨λ a, accessible (apply h a)⟩
|
||||
⟨fun a => accessible (apply h a)⟩
|
||||
end TC
|
||||
|
||||
-- less-than is well-founded
|
||||
def Nat.ltWf : WellFounded Nat.lt :=
|
||||
⟨Nat.rec
|
||||
(Acc.intro 0 (λ n h, absurd h (Nat.notLtZero n)))
|
||||
(λ n ih, Acc.intro (Nat.succ n) $ λ m h,
|
||||
(Acc.intro 0 (fun n h => absurd h (Nat.notLtZero n)))
|
||||
(fun n ih => Acc.intro (Nat.succ n) $ fun m h =>
|
||||
Or.elim (Nat.eqOrLtOfLe (Nat.leOfSuccLeSucc h))
|
||||
(λ e, Eq.substr e ih) (Acc.inv ih))⟩
|
||||
(fun e => Eq.substr e ih) (Acc.inv ih))⟩
|
||||
|
||||
def measure {α : Sort u} : (α → Nat) → α → α → Prop :=
|
||||
InvImage (λ a b, a < b)
|
||||
InvImage (fun a b => a < b)
|
||||
|
||||
def measureWf {α : Sort u} (f : α → Nat) : WellFounded (measure f) :=
|
||||
InvImage.wf f Nat.ltWf
|
||||
|
|
@ -173,23 +173,23 @@ variables {α : Type u} {β : Type v}
|
|||
variables {ra : α → α → Prop} {rb : β → β → Prop}
|
||||
|
||||
def lexAccessible {a} (aca : Acc ra a) (acb : ∀ b, Acc rb b): ∀ b, Acc (Lex ra rb) (a, b) :=
|
||||
Acc.ndrecOn aca $ λ xa aca iha b,
|
||||
Acc.ndrecOn (acb b) $ λ xb acb ihb,
|
||||
Acc.intro (xa, xb) $ λ p lt,
|
||||
Acc.ndrecOn aca $ fun xa aca iha b =>
|
||||
Acc.ndrecOn (acb b) $ fun xb acb ihb =>
|
||||
Acc.intro (xa, xb) $ fun p lt =>
|
||||
have aux : xa = xa → xb = xb → Acc (Lex ra rb) p, from
|
||||
@Prod.Lex.recOn α β ra rb (λ p₁ p₂ _, fst p₂ = xa → snd p₂ = xb → Acc (Lex ra rb) p₁)
|
||||
@Prod.Lex.recOn α β ra rb (fun p₁ p₂ _ => fst p₂ = xa → snd p₂ = xb → Acc (Lex ra rb) p₁)
|
||||
p (xa, xb) lt
|
||||
(λ a₁ b₁ a₂ b₂ h (Eq₂ : a₂ = xa) (Eq₃ : b₂ = xb), iha a₁ (Eq.recOn Eq₂ h) b₁)
|
||||
(λ a b₁ b₂ h (Eq₂ : a = xa) (Eq₃ : b₂ = xb), Eq.recOn Eq₂.symm (ihb b₁ (Eq.recOn Eq₃ h))),
|
||||
(fun (a₁ b₁ a₂ b₂ h) (Eq₂ : a₂ = xa) (Eq₃ : b₂ = xb) => iha a₁ (Eq.recOn Eq₂ h) b₁)
|
||||
(fun (a b₁ b₂ h) (Eq₂ : a = xa) (Eq₃ : b₂ = xb) => Eq.recOn Eq₂.symm (ihb b₁ (Eq.recOn Eq₃ h))),
|
||||
aux rfl rfl
|
||||
|
||||
-- The lexicographical order of well founded relations is well-founded
|
||||
def lexWf (ha : WellFounded ra) (hb : WellFounded rb) : WellFounded (Lex ra rb) :=
|
||||
⟨λ p, casesOn p $ λ a b, lexAccessible (apply ha a) (WellFounded.apply hb) b⟩
|
||||
⟨fun p => casesOn p $ fun a b => lexAccessible (apply ha a) (WellFounded.apply hb) b⟩
|
||||
|
||||
-- relational product is a Subrelation of the Lex
|
||||
def rprodSubLex : ∀ a b, Rprod ra rb a b → Lex ra rb a b :=
|
||||
@Prod.Rprod.rec _ _ ra rb (λ a b _, Lex ra rb a b) (λ a₁ b₁ a₂ b₂ h₁ h₂, Lex.left rb b₁ b₂ h₁)
|
||||
@Prod.Rprod.rec _ _ ra rb (fun a b _ => Lex ra rb a b) (fun a₁ b₁ a₂ b₂ h₁ h₂ => Lex.left rb b₁ b₂ h₁)
|
||||
|
||||
-- The relational product of well founded relations is well-founded
|
||||
def rprodWf (ha : WellFounded ra) (hb : WellFounded rb) : WellFounded (Rprod ra rb) :=
|
||||
|
|
@ -218,51 +218,51 @@ variables {α : Sort u} {β : α → Sort v}
|
|||
variables {r : α → α → Prop} {s : Π a : α, β a → β a → Prop}
|
||||
|
||||
def lexAccessible {a} (aca : Acc r a) (acb : ∀ a, WellFounded (s a)) : ∀ (b : β a), Acc (Lex r s) ⟨a, b⟩ :=
|
||||
Acc.ndrecOn aca $ λ xa aca (iha : ∀ y, r y xa → ∀ b : β y, Acc (Lex r s) ⟨y, b⟩) (b : β xa),
|
||||
Acc.ndrecOn (WellFounded.apply (acb xa) b) $ λ xb acb (ihb : ∀ (y : β xa), s xa y xb → Acc (Lex r s) ⟨xa, y⟩),
|
||||
Acc.intro ⟨xa, xb⟩ $ λ p (lt : Lex r s p ⟨xa, xb⟩),
|
||||
Acc.ndrecOn aca $ fun (xa aca) (iha : ∀ y, r y xa → ∀ b : β y, Acc (Lex r s) ⟨y, b⟩) (b : β xa) =>
|
||||
Acc.ndrecOn (WellFounded.apply (acb xa) b) $ fun xb acb (ihb : ∀ (y : β xa), s xa y xb → Acc (Lex r s) ⟨xa, y⟩) =>
|
||||
Acc.intro ⟨xa, xb⟩ $ fun (p) (lt : Lex r s p ⟨xa, xb⟩) =>
|
||||
have aux : xa = xa → xb ≅ xb → Acc (Lex r s) p, from
|
||||
@PSigma.Lex.recOn α β r s (λ p₁ p₂ _, p₂.1 = xa → p₂.2 ≅ xb → Acc (Lex r s) p₁)
|
||||
@PSigma.Lex.recOn α β r s (fun p₁ p₂ _ => p₂.1 = xa → p₂.2 ≅ xb → Acc (Lex r s) p₁)
|
||||
p ⟨xa, xb⟩ lt
|
||||
(λ (a₁ : α) (b₁ : β a₁) (a₂ : α) (b₂ : β a₂) (h : r a₁ a₂) (Eq₂ : a₂ = xa) (Eq₃ : b₂ ≅ xb),
|
||||
(fun (a₁ : α) (b₁ : β a₁) (a₂ : α) (b₂ : β a₂) (h : r a₁ a₂) (Eq₂ : a₂ = xa) (Eq₃ : b₂ ≅ xb) =>
|
||||
have aux : (∀ (y : α), r y xa → ∀ (b : β y), Acc (Lex r s) ⟨y, b⟩) →
|
||||
r a₁ a₂ → ∀ (b₁ : β a₁), Acc (Lex r s) ⟨a₁, b₁⟩,
|
||||
from Eq.subst Eq₂ (λ iha h b₁, iha a₁ h b₁),
|
||||
from Eq.subst Eq₂ (fun iha h b₁ => iha a₁ h b₁),
|
||||
aux iha h b₁)
|
||||
(λ (a : α) (b₁ b₂ : β a) (h : s a b₁ b₂) (Eq₂ : a = xa) (Eq₃ : b₂ ≅ xb),
|
||||
(fun (a : α) (b₁ b₂ : β a) (h : s a b₁ b₂) (Eq₂ : a = xa) (Eq₃ : b₂ ≅ xb) =>
|
||||
have aux : ∀ (xb : β xa), (∀ (y : β xa), s xa y xb → Acc (s xa) y) →
|
||||
(∀ (y : β xa), s xa y xb → Acc (Lex r s) ⟨xa, y⟩) →
|
||||
Lex r s p ⟨xa, xb⟩ → ∀ (b₁ : β a), s a b₁ b₂ → b₂ ≅ xb → Acc (Lex r s) ⟨a, b₁⟩,
|
||||
from Eq.subst Eq₂ $ λ xb acb ihb lt b₁ h Eq₃,
|
||||
from Eq.subst Eq₂ $ fun xb acb ihb lt b₁ h Eq₃ =>
|
||||
have newEq₃ : b₂ = xb, from eqOfHeq Eq₃,
|
||||
have aux : (∀ (y : β a), s a y xb → Acc (Lex r s) ⟨a, y⟩) →
|
||||
∀ (b₁ : β a), s a b₁ b₂ → Acc (Lex r s) ⟨a, b₁⟩,
|
||||
from Eq.subst newEq₃ (λ ihb b₁ h, ihb b₁ h),
|
||||
from Eq.subst newEq₃ (fun ihb b₁ h => ihb b₁ h),
|
||||
aux ihb b₁ h,
|
||||
aux xb acb ihb lt b₁ h Eq₃),
|
||||
aux rfl (Heq.refl xb)
|
||||
|
||||
-- The lexicographical order of well founded relations is well-founded
|
||||
def lexWf (ha : WellFounded r) (hb : ∀ x, WellFounded (s x)) : WellFounded (Lex r s) :=
|
||||
WellFounded.intro $ λ ⟨a, b⟩, lexAccessible (WellFounded.apply ha a) hb b
|
||||
WellFounded.intro $ fun ⟨a, b⟩ => lexAccessible (WellFounded.apply ha a) hb b
|
||||
end
|
||||
|
||||
section
|
||||
variables {α : Sort u} {β : Sort v}
|
||||
|
||||
def lexNdep (r : α → α → Prop) (s : β → β → Prop) :=
|
||||
Lex r (λ a : α, s)
|
||||
Lex r (fun a => s)
|
||||
|
||||
def lexNdepWf {r : α → α → Prop} {s : β → β → Prop} (ha : WellFounded r) (hb : WellFounded s)
|
||||
: WellFounded (lexNdep r s) :=
|
||||
WellFounded.intro $ λ ⟨a, b⟩, lexAccessible (WellFounded.apply ha a) (λ x, hb) b
|
||||
WellFounded.intro $ fun ⟨a, b⟩ => lexAccessible (WellFounded.apply ha a) (fun x => hb) b
|
||||
end
|
||||
|
||||
section
|
||||
variables {α : Sort u} {β : Sort v}
|
||||
|
||||
-- Reverse lexicographical order based on r and s
|
||||
inductive RevLex (r : α → α → Prop) (s : β → β → Prop) : @PSigma α (λ a, β) → @PSigma α (λ a, β) → Prop
|
||||
inductive RevLex (r : α → α → Prop) (s : β → β → Prop) : @PSigma α (fun a => β) → @PSigma α (fun a => β) → Prop
|
||||
| left : ∀ {a₁ a₂ : α} (b : β), r a₁ a₂ → RevLex ⟨a₁, b⟩ ⟨a₂, b⟩
|
||||
| right : ∀ (a₁ : α) {b₁ : β} (a₂ : α) {b₂ : β}, s b₁ b₂ → RevLex ⟨a₁, b₁⟩ ⟨a₂, b₂⟩
|
||||
end
|
||||
|
|
@ -273,29 +273,29 @@ variables {α : Sort u} {β : Sort v}
|
|||
variables {r : α → α → Prop} {s : β → β → Prop}
|
||||
|
||||
def revLexAccessible {b} (acb : Acc s b) (aca : ∀ a, Acc r a): ∀ a, Acc (RevLex r s) ⟨a, b⟩ :=
|
||||
Acc.recOn acb $ λ xb acb (ihb : ∀ y, s y xb → ∀ a, Acc (RevLex r s) ⟨a, y⟩) a,
|
||||
Acc.recOn (aca a) $ λ xa aca (iha : ∀ y, r y xa → Acc (RevLex r s) (mk y xb)),
|
||||
Acc.intro ⟨xa, xb⟩ $ λ p (lt : RevLex r s p ⟨xa, xb⟩),
|
||||
Acc.recOn acb $ fun (xb acb) (ihb : ∀ y, s y xb → ∀ a, Acc (RevLex r s) ⟨a, y⟩) (a) =>
|
||||
Acc.recOn (aca a) $ fun (xa aca) (iha : ∀ y, r y xa → Acc (RevLex r s) (mk y xb)) =>
|
||||
Acc.intro ⟨xa, xb⟩ $ fun (p) (lt : RevLex r s p ⟨xa, xb⟩) =>
|
||||
have aux : xa = xa → xb = xb → Acc (RevLex r s) p, from
|
||||
@RevLex.recOn α β r s (λ p₁ p₂ _, fst p₂ = xa → snd p₂ = xb → Acc (RevLex r s) p₁)
|
||||
@RevLex.recOn α β r s (fun p₁ p₂ _ => fst p₂ = xa → snd p₂ = xb → Acc (RevLex r s) p₁)
|
||||
p ⟨xa, xb⟩ lt
|
||||
(λ a₁ a₂ b (h : r a₁ a₂) (Eq₂ : a₂ = xa) (Eq₃ : b = xb),
|
||||
(fun (a₁ a₂ b) (h : r a₁ a₂) (Eq₂ : a₂ = xa) (Eq₃ : b = xb) =>
|
||||
show Acc (RevLex r s) ⟨a₁, b⟩, from
|
||||
have r₁ : r a₁ xa, from Eq.recOn Eq₂ h,
|
||||
have aux : Acc (RevLex r s) ⟨a₁, xb⟩, from iha a₁ r₁,
|
||||
Eq.recOn (Eq.symm Eq₃) aux)
|
||||
(λ a₁ b₁ a₂ b₂ (h : s b₁ b₂) (Eq₂ : a₂ = xa) (Eq₃ : b₂ = xb),
|
||||
(fun (a₁ b₁ a₂ b₂) (h : s b₁ b₂) (Eq₂ : a₂ = xa) (Eq₃ : b₂ = xb) =>
|
||||
show Acc (RevLex r s) (mk a₁ b₁), from
|
||||
have s₁ : s b₁ xb, from Eq.recOn Eq₃ h,
|
||||
ihb b₁ s₁ a₁),
|
||||
aux rfl rfl
|
||||
|
||||
def revLexWf (ha : WellFounded r) (hb : WellFounded s) : WellFounded (RevLex r s) :=
|
||||
WellFounded.intro $ λ ⟨a, b⟩, revLexAccessible (apply hb b) (WellFounded.apply ha) a
|
||||
WellFounded.intro $ fun ⟨a, b⟩ => revLexAccessible (apply hb b) (WellFounded.apply ha) a
|
||||
end
|
||||
|
||||
section
|
||||
def skipLeft (α : Type u) {β : Type v} (s : β → β → Prop) : @PSigma α (λ a, β) → @PSigma α (λ a, β) → Prop :=
|
||||
def skipLeft (α : Type u) {β : Type v} (s : β → β → Prop) : @PSigma α (fun a => β) → @PSigma α (fun a => β) → Prop :=
|
||||
RevLex emptyRelation s
|
||||
|
||||
def skipLeftWf (α : Type u) {β : Type v} {s : β → β → Prop} (hb : WellFounded s) : WellFounded (skipLeft α s) :=
|
||||
|
|
@ -306,6 +306,6 @@ RevLex.right _ _ _ h
|
|||
end
|
||||
|
||||
instance HasWellFounded {α : Type u} {β : α → Type v} [s₁ : HasWellFounded α] [s₂ : ∀ a, HasWellFounded (β a)] : HasWellFounded (PSigma β) :=
|
||||
{r := Lex s₁.r (λ a, (s₂ a).r), wf := lexWf s₁.wf (λ a, (s₂ a).wf)}
|
||||
{r := Lex s₁.r (fun a => (s₂ a).r), wf := lexWf s₁.wf (fun a => (s₂ a).wf)}
|
||||
|
||||
end PSigma
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ expr parse_curly_bracket(parser & p, unsigned, expr const *, pos_info const & po
|
|||
} else if (p.curr_is_token(get_period_tk())) {
|
||||
p.next();
|
||||
return parse_qualified_structure_instance(p, id, id_pos);
|
||||
} else if (p.curr_is_token(get_assign_tk()) || p.curr_is_token(get_fieldarrow_tk())) {
|
||||
} else if (p.curr_is_token(get_assign_tk())) {
|
||||
return parse_structure_instance(p, id);
|
||||
} else if (p.curr_is_token(get_membership_tk()) || p.curr_is_token(get_in_tk())) {
|
||||
p.next();
|
||||
|
|
|
|||
|
|
@ -653,13 +653,13 @@ static expr parse_lambda_binder(parser & p, pos_info const & pos) {
|
|||
p.add_local(local);
|
||||
parser::local_scope scope2(p, new_env);
|
||||
expr body;
|
||||
if (p.curr_is_token(get_comma_tk())) {
|
||||
if (/* p.curr_is_token(get_comma_tk()) || */ p.curr_is_token(get_darrow_tk())) {
|
||||
p.next();
|
||||
body = p.parse_expr();
|
||||
} else if (p.curr_is_token(get_langle_tk())) {
|
||||
body = parse_lambda_core(p, pos);
|
||||
} else {
|
||||
p.maybe_throw_error({"invalid lambda expression, ',' or '⟨' expected", p.pos()});
|
||||
p.maybe_throw_error({"invalid lambda expression, ',', '=>' or '⟨' expected", p.pos()});
|
||||
body = p.parse_expr();
|
||||
}
|
||||
return p.rec_save_pos(Fun(locals, body, p), pos);
|
||||
|
|
@ -677,7 +677,7 @@ static expr parse_lambda_constructor(parser & p, pos_info const & ini_pos) {
|
|||
for (expr const & local : locals)
|
||||
p.add_local(local);
|
||||
expr body;
|
||||
if (p.curr_is_token(get_comma_tk())) {
|
||||
if (/* p.curr_is_token(get_comma_tk()) || */ p.curr_is_token(get_darrow_tk())) {
|
||||
p.next();
|
||||
body = p.parse_expr();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ void decl_attributes::parse_compact(parser & p) {
|
|||
parse_core(p, true);
|
||||
}
|
||||
|
||||
void decl_attributes::set_attribute(environment const & env, name const & attr_name) {
|
||||
void decl_attributes::set_attribute(environment const & /* env */, name const & attr_name) {
|
||||
if (is_new_attribute(attr_name)) {
|
||||
// Temporary Hack... ignore attr_data_ptr
|
||||
syntax args(box(0));
|
||||
|
|
@ -192,7 +192,7 @@ bool decl_attributes::has_attribute(list<new_entry> const & entries, name const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool decl_attributes::has_attribute(environment const & env, name const & attr_name) const {
|
||||
bool decl_attributes::has_attribute(environment const & /* env */, name const & attr_name) const {
|
||||
if (is_new_attribute(attr_name)) {
|
||||
return has_attribute(m_after_tc_entries, attr_name) || has_attribute(m_after_comp_entries, attr_name);
|
||||
} else {
|
||||
|
|
@ -218,7 +218,7 @@ environment decl_attributes::apply_new_entries(environment env, list<new_entry>
|
|||
return env;
|
||||
}
|
||||
|
||||
environment decl_attributes::apply_after_tc(environment env, io_state const & ios, name const & d) const {
|
||||
environment decl_attributes::apply_after_tc(environment env, io_state const & /* ios */, name const & d) const {
|
||||
return apply_new_entries(env, m_after_tc_entries, d);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ void init_token_table(token_table & t) {
|
|||
{"Type", g_max_prec}, {"Type*", g_max_prec}, {"Sort", g_max_prec}, {"Sort*", g_max_prec},
|
||||
{"(:", g_max_prec}, {":)", 0}, {".(", g_max_prec}, {"._", g_max_prec},
|
||||
{"⟨", g_max_prec}, {"⟩", 0}, {"^", 0},
|
||||
{"//", 0}, {"|", 0}, {"with", 0}, {"without", 0}, {"..", 0}, {"...", 0}, {",", 0},
|
||||
{"//", 0}, {"|", 0}, {"with", 0}, {"without", 0}, {"..", 0}, {"...", 0}, {",", 0}, {"=>", 0},
|
||||
{".", 0}, {":", 0}, {"!", 0}, {":=", 0}, {"--", 0}, {"#", g_max_prec},
|
||||
{"/-", 0}, {"/--", 0}, {"/-!", 0}, {"begin", g_max_prec}, {"using", 0},
|
||||
{"@@", g_max_prec}, {"@", g_max_prec}, {"@&", g_max_prec},
|
||||
|
|
@ -136,6 +136,7 @@ void init_token_table(token_table & t) {
|
|||
}
|
||||
t = add_token(t, "→", "->", get_arrow_prec());
|
||||
t = add_token(t, "←", "<-", 0);
|
||||
t = add_token(t, "⇒", "=>", 0);
|
||||
|
||||
auto it4 = cmd_aliases;
|
||||
while (it4->first) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ static name const * g_aliases_tk = nullptr;
|
|||
static name const * g_period_tk = nullptr;
|
||||
static name const * g_backtick_tk = nullptr;
|
||||
static name const * g_dslash_tk = nullptr;
|
||||
static name const * g_fieldarrow_tk = nullptr;
|
||||
static name const * g_placeholder_tk = nullptr;
|
||||
static name const * g_colon_tk = nullptr;
|
||||
static name const * g_semicolon_tk = nullptr;
|
||||
|
|
@ -67,6 +66,7 @@ static name const * g_classes_tk = nullptr;
|
|||
static name const * g_attributes_tk = nullptr;
|
||||
static name const * g_arrow_tk = nullptr;
|
||||
static name const * g_larrow_tk = nullptr;
|
||||
static name const * g_darrow_tk = nullptr;
|
||||
static name const * g_hiding_tk = nullptr;
|
||||
static name const * g_example_tk = nullptr;
|
||||
static name const * g_exposing_tk = nullptr;
|
||||
|
|
@ -134,7 +134,6 @@ void initialize_tokens() {
|
|||
g_period_tk = new name{"."};
|
||||
g_backtick_tk = new name{"`"};
|
||||
g_dslash_tk = new name{"//"};
|
||||
g_fieldarrow_tk = new name{"~>"};
|
||||
g_placeholder_tk = new name{"_"};
|
||||
g_colon_tk = new name{":"};
|
||||
g_semicolon_tk = new name{";"};
|
||||
|
|
@ -194,6 +193,7 @@ void initialize_tokens() {
|
|||
g_attributes_tk = new name{"attributes"};
|
||||
g_arrow_tk = new name{"->"};
|
||||
g_larrow_tk = new name{"<-"};
|
||||
g_darrow_tk = new name{"=>"};
|
||||
g_hiding_tk = new name{"hiding"};
|
||||
g_example_tk = new name{"example"};
|
||||
g_exposing_tk = new name{"exposing"};
|
||||
|
|
@ -262,7 +262,6 @@ void finalize_tokens() {
|
|||
delete g_period_tk;
|
||||
delete g_backtick_tk;
|
||||
delete g_dslash_tk;
|
||||
delete g_fieldarrow_tk;
|
||||
delete g_placeholder_tk;
|
||||
delete g_colon_tk;
|
||||
delete g_semicolon_tk;
|
||||
|
|
@ -322,6 +321,7 @@ void finalize_tokens() {
|
|||
delete g_attributes_tk;
|
||||
delete g_arrow_tk;
|
||||
delete g_larrow_tk;
|
||||
delete g_darrow_tk;
|
||||
delete g_hiding_tk;
|
||||
delete g_example_tk;
|
||||
delete g_exposing_tk;
|
||||
|
|
@ -389,7 +389,6 @@ name const & get_aliases_tk() { return *g_aliases_tk; }
|
|||
name const & get_period_tk() { return *g_period_tk; }
|
||||
name const & get_backtick_tk() { return *g_backtick_tk; }
|
||||
name const & get_dslash_tk() { return *g_dslash_tk; }
|
||||
name const & get_fieldarrow_tk() { return *g_fieldarrow_tk; }
|
||||
name const & get_placeholder_tk() { return *g_placeholder_tk; }
|
||||
name const & get_colon_tk() { return *g_colon_tk; }
|
||||
name const & get_semicolon_tk() { return *g_semicolon_tk; }
|
||||
|
|
@ -449,6 +448,7 @@ name const & get_classes_tk() { return *g_classes_tk; }
|
|||
name const & get_attributes_tk() { return *g_attributes_tk; }
|
||||
name const & get_arrow_tk() { return *g_arrow_tk; }
|
||||
name const & get_larrow_tk() { return *g_larrow_tk; }
|
||||
name const & get_darrow_tk() { return *g_darrow_tk; }
|
||||
name const & get_hiding_tk() { return *g_hiding_tk; }
|
||||
name const & get_example_tk() { return *g_example_tk; }
|
||||
name const & get_exposing_tk() { return *g_exposing_tk; }
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ name const & get_aliases_tk();
|
|||
name const & get_period_tk();
|
||||
name const & get_backtick_tk();
|
||||
name const & get_dslash_tk();
|
||||
name const & get_fieldarrow_tk();
|
||||
name const & get_placeholder_tk();
|
||||
name const & get_colon_tk();
|
||||
name const & get_semicolon_tk();
|
||||
|
|
@ -69,6 +68,7 @@ name const & get_classes_tk();
|
|||
name const & get_attributes_tk();
|
||||
name const & get_arrow_tk();
|
||||
name const & get_larrow_tk();
|
||||
name const & get_darrow_tk();
|
||||
name const & get_hiding_tk();
|
||||
name const & get_example_tk();
|
||||
name const & get_exposing_tk();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ aliases aliases
|
|||
period .
|
||||
backtick `
|
||||
dslash //
|
||||
fieldarrow ~>
|
||||
placeholder _
|
||||
colon :
|
||||
semicolon ;
|
||||
|
|
@ -62,6 +61,7 @@ classes classes
|
|||
attributes attributes
|
||||
arrow ->
|
||||
larrow <-
|
||||
darrow =>
|
||||
hiding hiding
|
||||
example example
|
||||
exposing exposing
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ do
|
|||
IO.println (toString a.sz);
|
||||
let a := foo a;
|
||||
IO.println (toString a);
|
||||
let a := a.map (+10);
|
||||
let a := a.map (fun a => a + 10);
|
||||
IO.println (toString a);
|
||||
IO.println (toString a.sz);
|
||||
let a1 := a.pop;
|
||||
|
|
@ -21,7 +21,7 @@ do
|
|||
IO.println (toString a2);
|
||||
let a2 := a.pop;
|
||||
IO.println a2;
|
||||
IO.println $ (([1, 2, 3, 4].toArray).map (+2)).map toString;
|
||||
IO.println $ (([1, 2, 3, 4].toArray).map (fun a => a + 2)).map toString;
|
||||
IO.println $ ([1, 2, 3, 4].toArray.extract 1 3);
|
||||
IO.println $ ([1, 2, 3, 4].toArray.extract 0 100);
|
||||
IO.println $ ([1, 2, 3, 4].toArray.extract 1 1);
|
||||
|
|
@ -29,10 +29,10 @@ do
|
|||
IO.println [1,2,3,4].toArray.reverse;
|
||||
IO.println ([] : List Nat).toArray.reverse;
|
||||
IO.println [1,2,3].toArray.reverse;
|
||||
IO.println $ [1,2,3,4].toArray.filter (λ a, a % 2 == 0);
|
||||
IO.println $ [1,2,3,4,5].toArray.filter (λ a, a % 2 == 0);
|
||||
IO.println $ [1,2,3,4,5].toArray.filter (λ a, a % 2 == 1);
|
||||
IO.println $ [1,2,3,4].toArray.filter (>2);
|
||||
IO.println $ [1,2,3,4].toArray.filter (>10);
|
||||
IO.println $ [1,2,3,4].toArray.filter (>0);
|
||||
IO.println $ [1,2,3,4].toArray.filter (fun a => a % 2 == 0);
|
||||
IO.println $ [1,2,3,4,5].toArray.filter (fun a => a % 2 == 0);
|
||||
IO.println $ [1,2,3,4,5].toArray.filter (fun a => a % 2 == 1);
|
||||
IO.println $ [1,2,3,4].toArray.filter (fun a => a > 2);
|
||||
IO.println $ [1,2,3,4].toArray.filter (fun a => a > 10);
|
||||
IO.println $ [1,2,3,4].toArray.filter (fun a => a > 0);
|
||||
pure 0
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ let a1 := [2, 3, 5].toArray in
|
|||
let a2 := [4, 7, 9].toArray in
|
||||
let a3 := [4, 7, 8].toArray in
|
||||
do
|
||||
check (Array.isEqv a1 a2 (λ v w, v % 2 == w % 2));
|
||||
check (!Array.isEqv a1 a3 (λ v w, v % 2 == w % 2));
|
||||
check (Array.isEqv a1 a2 (fun v w => v % 2 == w % 2));
|
||||
check (!Array.isEqv a1 a3 (fun v w => v % 2 == w % 2));
|
||||
check (a1 ++ a2 == [2, 3, 5, 4, 7, 9].toArray);
|
||||
check (a1.any (>4));
|
||||
check (!a1.any (>10));
|
||||
check (a1.all (<10))
|
||||
check (a1.any (fun a => a > 4));
|
||||
check (!a1.any (fun a => a >10));
|
||||
check (a1.all (fun a => a < 10))
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ instance isMonad : Monad LazyList :=
|
|||
{ pure := @LazyList.pure, bind := @LazyList.bind, map := @LazyList.map }
|
||||
|
||||
instance : Alternative LazyList :=
|
||||
{ failure := λ _, nil,
|
||||
{ failure := fun _ => nil,
|
||||
orelse := @LazyList.append,
|
||||
.. LazyList.isMonad }
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ partial def filter (p : α → Bool) : LazyList α → LazyList α
|
|||
end LazyList
|
||||
|
||||
def fib : LazyList Nat :=
|
||||
LazyList.iterate₂ (+) 0 1
|
||||
LazyList.iterate₂ Nat.add 0 1
|
||||
|
||||
def iota (i : Nat := 0) : LazyList Nat :=
|
||||
LazyList.iterate Nat.succ i
|
||||
|
|
@ -123,5 +123,5 @@ def main : IO Unit :=
|
|||
do let n := 40;
|
||||
IO.println $ tst.isEmpty;
|
||||
IO.println $ tst.head;
|
||||
IO.println $ (fib.interleave (iota.map (+100))).approx n;
|
||||
IO.println $ (((iota.map (+10)).filter (λ v, v % 2 == 0)).approx n)
|
||||
IO.println $ (fib.interleave (iota.map (fun a => a + 100))).approx n;
|
||||
IO.println $ (((iota.map (fun a => a + 10)).filter (fun v => v % 2 == 0)).approx n)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
def f2 (n : Nat) (xs : List Nat) : List (List Nat) :=
|
||||
let ys := List.replicate n 0 in
|
||||
xs.map (λ x, x :: ys)
|
||||
xs.map (fun x => x :: ys)
|
||||
|
||||
def main : IO UInt32 :=
|
||||
let n := 100000 in
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ def check (b : Bool) : IO Unit :=
|
|||
unless b $ IO.println "ERROR"
|
||||
|
||||
def sz {α β : Type} {lt : α → α → Bool} (m : RBMap α β lt) : Nat :=
|
||||
m.fold (λ sz _ _, sz+1) 0
|
||||
m.fold (fun sz _ _ => sz+1) 0
|
||||
|
||||
def depth {α β : Type} {lt : α → α → Bool} (m : RBMap α β lt) : Nat :=
|
||||
m.depth Nat.max
|
||||
|
||||
def tst1 : IO Unit :=
|
||||
do let Map := RBMap String Nat (λ a b, a < b);
|
||||
do let Map := RBMap String Nat (fun a b => a < b);
|
||||
let m : Map := {};
|
||||
let m := m.insert "hello" 0;
|
||||
let m := m.insert "world" 1;
|
||||
|
|
@ -20,20 +20,20 @@ do let Map := RBMap String Nat (λ a b, a < b);
|
|||
pure ()
|
||||
|
||||
def tst2 : IO Unit :=
|
||||
do let Map := RBMap Nat Nat (λ a b, a < b);
|
||||
do let Map := RBMap Nat Nat (fun a b => a < b);
|
||||
let m : Map := {};
|
||||
let n : Nat := 10000;
|
||||
let m := n.fold (λ i (m : Map), m.insert i (i*10)) m;
|
||||
check (m.all (λ k v, v == k*10));
|
||||
let m := n.fold (fun i (m : Map) => m.insert i (i*10)) m;
|
||||
check (m.all (fun k v => v == k*10));
|
||||
check (sz m == n);
|
||||
IO.println (">> " ++ toString (depth m) ++ ", " ++ toString (sz m));
|
||||
let m := (n/2).fold (λ i (m : Map), m.erase (2*i)) m;
|
||||
check (m.all (λ k v, v == k*10));
|
||||
let m := (n/2).fold (fun i (m : Map) => m.erase (2*i)) m;
|
||||
check (m.all (fun k v => v == k*10));
|
||||
check (sz m == n / 2);
|
||||
IO.println (">> " ++ toString (depth m) ++ ", " ++ toString (sz m));
|
||||
pure ()
|
||||
|
||||
abbrev Map := RBMap Nat Nat (λ a b, a < b)
|
||||
abbrev Map := RBMap Nat Nat (fun a b => a < b)
|
||||
|
||||
def mkRandMap (max : Nat) : Nat → Map → Array (Nat × Nat) → IO (Map × Array (Nat × Nat))
|
||||
| 0 m a := pure (m, a)
|
||||
|
|
@ -51,11 +51,11 @@ def tst3 (seed : Nat) (n : Nat) (max : Nat) : IO Unit :=
|
|||
do IO.setRandSeed seed;
|
||||
(m, a) ← mkRandMap max n {} Array.empty;
|
||||
check (sz m == a.size);
|
||||
check (a.all (λ ⟨k, v⟩, m.find k == some v));
|
||||
check (a.all (fun ⟨k, v⟩ => m.find k == some v));
|
||||
IO.println ("tst3 size: " ++ toString a.size);
|
||||
let m := a.iterate m (λ i ⟨k, v⟩ m, if i.val % 2 == 0 then m.erase k else m);
|
||||
let m := a.iterate m (fun i ⟨k, v⟩ m => if i.val % 2 == 0 then m.erase k else m);
|
||||
check (sz m == a.size / 2);
|
||||
a.miterate () (λ i ⟨k, v⟩ _, when (i.val % 2 == 1) (check (m.find k == some v)));
|
||||
a.miterate () (fun i ⟨k, v⟩ _ => when (i.val % 2 == 1) (check (m.find k == some v)));
|
||||
IO.println ("tst3 after, depth: " ++ toString (depth m) ++ ", size: " ++ toString (sz m));
|
||||
pure ()
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ partial def addAux : Expr → Expr → Expr
|
|||
| f g := Add f g
|
||||
|
||||
def add (a b : Expr) : Expr :=
|
||||
-- dbgTrace (">> add (" ++ toString a ++ ", " ++ toString b ++ ")") $ λ _,
|
||||
-- dbgTrace (">> add (" ++ toString a ++ ", " ++ toString b ++ ")") $ fun _ =>
|
||||
addAux a b
|
||||
|
||||
-- set_option trace.compiler.borrowed_inference true
|
||||
|
|
@ -56,7 +56,7 @@ partial def mulAux : Expr → Expr → Expr
|
|||
| f g := Mul f g
|
||||
|
||||
def mul (a b : Expr) : Expr :=
|
||||
-- dbgTrace (">> mul (" ++ toString a ++ ", " ++ toString b ++ ")") $ λ _,
|
||||
-- dbgTrace (">> mul (" ++ toString a ++ ", " ++ toString b ++ ")") $ fun _ =>
|
||||
mulAux a b
|
||||
|
||||
def pow : Expr → Expr → Expr
|
||||
|
|
@ -75,7 +75,7 @@ def d (x : String) : Expr → Expr
|
|||
| (Var y) := if x = y then Val 1 else Val 0
|
||||
| (Add f g) := add (d f) (d g)
|
||||
| (Mul f g) :=
|
||||
-- dbgTrace (">> d (" ++ toString f ++ ", " ++ toString g ++ ")") $ λ _,
|
||||
-- dbgTrace (">> d (" ++ toString f ++ ", " ++ toString g ++ ")") $ fun _ =>
|
||||
add (mul f (d g)) (mul g (d f))
|
||||
| (Pow f g) := mul (pow f g) (add (mul (mul g (d f)) (pow f (Val (-1)))) (mul (ln f) (d g)))
|
||||
| (Ln f) := mul (d f) (pow f (Val (-1)))
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
def compute (v : Nat) : Thunk Nat :=
|
||||
⟨λ _, let xs := List.replicate 100000 v in xs.foldl (+) 0⟩
|
||||
⟨fun _ => let xs := List.replicate 100000 v in xs.foldl Nat.add 0⟩
|
||||
|
||||
@[noinline]
|
||||
def test (t : Thunk Nat) (n : Nat) : Nat :=
|
||||
n.repeat (λ r, t.get + r) 0
|
||||
n.repeat (fun r => t.get + r) 0
|
||||
|
||||
def main (xs : List String) : IO UInt32 :=
|
||||
IO.println (toString (test (compute 1) 100000)) *>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
def foo {m} [Monad m] [MonadExcept String m] [MonadState (Array Nat) m] : m Nat :=
|
||||
catch (do modify $ λ a : Array Nat, a.set 0 33;
|
||||
catch (do modify $ fun (a : Array Nat) => a.set 0 33;
|
||||
throw "error")
|
||||
(λ _, do a ← get; pure $ a.get 0)
|
||||
(fun _ => do a ← get; pure $ a.get 0)
|
||||
|
||||
def ex₁ : StateT (Array Nat) (ExceptT String Id) Nat :=
|
||||
foo
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ open value
|
|||
-- #eval value.op (op.mul 32) [[[ const 32, const 32 ]]]
|
||||
|
||||
-- This also works
|
||||
-- instance bvHasMul (w : Nat) : HasMul (value (bv w)) := ⟨λx y, value.op (op.mul w) [[[x, y]]]⟩
|
||||
-- instance bvHasMul (w : Nat) : HasMul (value (bv w)) := ⟨fun x y => w value.op (op.mul w) [[[x, y]]]⟩
|
||||
-- #eval const 32 * const 32
|
||||
|
||||
-- This works
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
#check @Array.mk
|
||||
|
||||
def v : Array Nat := @Array.mk Nat 10 (λ ⟨i, _⟩, i)
|
||||
def v : Array Nat := @Array.mk Nat 10 (fun ⟨i, _⟩ => i)
|
||||
|
||||
def w : Array Nat :=
|
||||
(mkArray 9 1).push 3
|
||||
|
||||
def f : Fin w.sz → Nat :=
|
||||
Array.casesOn w (λ _ f, f)
|
||||
Array.casesOn w (fun _ f => f)
|
||||
|
||||
def arraySum (a : Array Nat) : Nat :=
|
||||
a.foldl (+) 0
|
||||
a.foldl Nat.add 0
|
||||
|
||||
#exit
|
||||
|
||||
|
|
|
|||
|
|
@ -30,21 +30,21 @@ export coroutineResultCore (done yielded)
|
|||
| (mk k) a := k a
|
||||
|
||||
@[inline] protected def pure (b : β) : coroutine α δ β :=
|
||||
mk $ λ _, done b
|
||||
mk $ fun _ => done b
|
||||
|
||||
/-- Read the input argument passed to the coroutine.
|
||||
Remark: should we use a different Name? I added an instance [MonadReader] later. -/
|
||||
@[inline] protected def read : coroutine α δ α :=
|
||||
mk $ λ a, done a
|
||||
mk $ fun a => done a
|
||||
|
||||
/-- Run nested coroutine with transformed input argument. Like `ReaderT.adapt`, but
|
||||
cannot change the input Type. -/
|
||||
@[inline] protected def adapt (f : α → α) (c : coroutine α δ β) : coroutine α δ β :=
|
||||
mk $ λ a, c.resume (f a)
|
||||
mk $ fun a => c.resume (f a)
|
||||
|
||||
/-- Return the control to the invoker with Result `d` -/
|
||||
@[inline] protected def yield (d : δ) : coroutine α δ PUnit :=
|
||||
mk $ λ a : α, yielded d (coroutine.pure ⟨⟩)
|
||||
mk $ fun a => yielded d (coroutine.pure ⟨⟩)
|
||||
|
||||
/-
|
||||
TODO(Leo): following relations have been commented because Lean4 is currently
|
||||
|
|
@ -58,8 +58,8 @@ theorem directSubcoroutineWf : WellFounded (@directSubcoroutine α δ β) :=
|
|||
begin
|
||||
Constructor, intro c,
|
||||
apply @coroutine.ind _ _ _
|
||||
(λ c, Acc directSubcoroutine c)
|
||||
(λ r, ∀ (d : δ) (c : coroutine α δ β), r = yielded d c → Acc directSubcoroutine c),
|
||||
(fun c => Acc directSubcoroutine c)
|
||||
(fun r => ∀ (d : δ) (c : coroutine α δ β), r = yielded d c → Acc directSubcoroutine c),
|
||||
{ intros k ih, dsimp at ih, Constructor, intros c' h, cases h, apply ih hA hD, assumption },
|
||||
{ intros, contradiction },
|
||||
{ intros d c ih d₁ c₁ Heq, injection Heq, subst c, assumption }
|
||||
|
|
@ -76,12 +76,12 @@ Tc.wf directSubcoroutineWf
|
|||
-- Local instances for proving termination by well founded relation
|
||||
|
||||
def bindWfInst : HasWellFounded (Σ' a : coroutine α δ β, (β → coroutine α δ γ)) :=
|
||||
{ r := Psigma.Lex directSubcoroutine (λ _, emptyRelation),
|
||||
wf := Psigma.lexWf directSubcoroutineWf (λ _, emptyWf) }
|
||||
{ r := Psigma.Lex directSubcoroutine (fun _ => emptyRelation),
|
||||
wf := Psigma.lexWf directSubcoroutineWf (fun _ => emptyWf) }
|
||||
|
||||
def pipeWfInst : HasWellFounded (Σ' a : coroutine α δ β, coroutine δ γ β) :=
|
||||
{ r := Psigma.Lex directSubcoroutine (λ _, emptyRelation),
|
||||
wf := Psigma.lexWf directSubcoroutineWf (λ _, emptyWf) }
|
||||
{ r := Psigma.Lex directSubcoroutine (fun _ => emptyRelation),
|
||||
wf := Psigma.lexWf directSubcoroutineWf (fun _ => emptyWf) }
|
||||
|
||||
local attribute [instance] wfInst₁ wfInst₂
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ open wellFoundedTactics
|
|||
/- TODO: remove `unsafe` keyword after we restore well-founded recursion -/
|
||||
|
||||
@[inlineIfReduce] protected unsafe def bind : coroutine α δ β → (β → coroutine α δ γ) → coroutine α δ γ
|
||||
| (mk k) f := mk $ λ a,
|
||||
| (mk k) f := mk $ fun a =>
|
||||
match k a, rfl : ∀ (n : _), n = k a → _ with
|
||||
| done b, _ := coroutine.resume (f b) a
|
||||
| yielded d c, h :=
|
||||
|
|
@ -101,7 +101,7 @@ open wellFoundedTactics
|
|||
-- usingWellFounded { decTac := unfoldWfRel >> processLex (tactic.assumption) }
|
||||
|
||||
unsafe def pipe : coroutine α δ β → coroutine δ γ β → coroutine α γ β
|
||||
| (mk k₁) (mk k₂) := mk $ λ a,
|
||||
| (mk k₁) (mk k₂) := mk $ fun a =>
|
||||
match k₁ a, rfl : ∀ (n : _), n = k₁ a → _ with
|
||||
| done b, h := done b
|
||||
| yielded d k₁', h :=
|
||||
|
|
@ -120,7 +120,7 @@ private unsafe def finishAux (f : δ → α) : coroutine α δ β → α → Lis
|
|||
|
||||
/-- Run a coroutine to completion, feeding back yielded items after transforming them with `f`. -/
|
||||
unsafe def finish (f : δ → α) : coroutine α δ β → α → List δ × β :=
|
||||
λ k a, finishAux f k a []
|
||||
fun k a => finishAux f k a []
|
||||
|
||||
unsafe instance : Monad (coroutine α δ) :=
|
||||
{ pure := @coroutine.pure _ _,
|
||||
|
|
@ -140,7 +140,7 @@ instance (α : Type u) (δ : Type v) : monadCoroutine α δ (coroutine α δ) :=
|
|||
|
||||
instance monadCoroutineTrans (α : Type u) (δ : Type v) (m : Type w → Type r) (n : Type w → Type s)
|
||||
[HasMonadLift m n] [monadCoroutine α δ m] : monadCoroutine α δ n :=
|
||||
{ yield := λ d, monadLift (monadCoroutine.yield d : m _) }
|
||||
{ yield := fun d => monadLift (monadCoroutine.yield d : m _) }
|
||||
|
||||
export monadCoroutine (yield)
|
||||
|
||||
|
|
|
|||
|
|
@ -67,40 +67,40 @@ inductive eff (effs : List effect) (α : Type)
|
|||
|
||||
def eff.bind {α β : Type} {effs : List effect} : eff effs α → (α → eff effs β) → eff effs β
|
||||
| (eff.pure a) f := f a
|
||||
| (@eff.impure _ _ β u k) f := eff.impure u (λ b, eff.bind (k b) f)
|
||||
| (@eff.impure _ _ β u k) f := eff.impure u (fun b => eff.bind (k b) f)
|
||||
|
||||
instance (effs) : Monad (eff effs) :=
|
||||
{ pure := λ α, eff.pure,
|
||||
bind := λ α β, eff.bind }
|
||||
{ pure := fun α => eff.pure,
|
||||
bind := fun α β => eff.bind }
|
||||
|
||||
@[inline] def eff.send {e : effect} {effs α} [member e effs] : e α → eff effs α :=
|
||||
λ x, eff.impure (union.inj x) pure
|
||||
fun x => eff.impure (union.inj x) pure
|
||||
|
||||
@[inline] def eff.sendM {e : effect} {effs α} [Monad e] [lastMember e effs] : e α → eff effs α :=
|
||||
λ x, eff.impure (union.inj x) pure
|
||||
fun x => eff.impure (union.inj x) pure
|
||||
|
||||
@[inline] def eff.handleRelay {e : effect} {effs α β} (ret : β → eff effs α)
|
||||
(h : ∀ {β}, e β → (β → eff effs α) → eff effs α) : eff (e :: effs) β → eff effs α
|
||||
| (eff.pure a) := ret a
|
||||
| (@eff.impure _ _ β u k) := match u.decomp with
|
||||
| Sum.inl e := h e (λ b, eff.handleRelay (k b))
|
||||
| Sum.inr u := eff.impure u (λ b, eff.handleRelay (k b))
|
||||
| Sum.inl e := h e (fun b => eff.handleRelay (k b))
|
||||
| Sum.inr u := eff.impure u (fun b => eff.handleRelay (k b))
|
||||
|
||||
|
||||
@[inline] def eff.handleRelayΣ {e : effect} {effs α β} {σ : Type} (ret : σ → β → eff effs α)
|
||||
(h : ∀ {β}, σ → e β → (σ → β → eff effs α) → eff effs α) : σ → eff (e :: effs) β → eff effs α
|
||||
| st (eff.pure a) := ret st a
|
||||
| st (@eff.impure _ _ β u k) := match u.decomp with
|
||||
| Sum.inl e := h st e (λ st b, eff.handleRelayΣ st (k b))
|
||||
| Sum.inr u := eff.impure u (λ b, eff.handleRelayΣ st (k b))
|
||||
| Sum.inl e := h st e (fun st b => eff.handleRelayΣ st (k b))
|
||||
| Sum.inr u := eff.impure u (fun b => eff.handleRelayΣ st (k b))
|
||||
|
||||
|
||||
@[inline] def eff.interpose (e : effect) {effs α β} [member e effs] (ret : β → eff effs α)
|
||||
(h : ∀ {β}, e β → (β → eff effs α) → eff effs α) : eff effs β → eff effs α
|
||||
| (eff.pure a) := ret a
|
||||
| (@eff.impure _ _ β u k) := match u.prj e with
|
||||
| some e := h e (λ b, eff.interpose (k b))
|
||||
| none := eff.impure u (λ b, eff.interpose (k b))
|
||||
| some e := h e (fun b => eff.interpose (k b))
|
||||
| none := eff.impure u (fun b => eff.interpose (k b))
|
||||
|
||||
|
||||
inductive Reader (ρ : Type) : Type → Type
|
||||
|
|
@ -110,7 +110,7 @@ inductive Reader (ρ : Type) : Type → Type
|
|||
instance {ρ effs} [member (Reader ρ) effs] : MonadReader ρ (eff effs) := ⟨eff.read⟩
|
||||
|
||||
@[inline] def Reader.run {ρ effs α} (env : ρ) : eff (Reader ρ :: effs) α → eff effs α :=
|
||||
eff.handleRelay pure (λ β x k, by cases x; exact k env)
|
||||
eff.handleRelay pure (fun β x k => by cases x; exact k env)
|
||||
|
||||
|
||||
inductive State (σ : Type) : Type → Type
|
||||
|
|
@ -120,13 +120,13 @@ inductive State (σ : Type) : Type → Type
|
|||
@[inline] def eff.get {σ effs} [member (State σ) effs] : eff effs σ := eff.send State.get
|
||||
@[inline] def eff.put {σ effs} [member (State σ) effs] (s : σ) : eff effs Unit := eff.send (State.put s)
|
||||
instance {σ effs} [member (State σ) effs] : MonadState σ (eff effs) :=
|
||||
⟨λ α x, do st ← eff.get;
|
||||
⟨fun α x => do st ← eff.get;
|
||||
let ⟨a, s'⟩ := x.run st;
|
||||
eff.put s';
|
||||
pure a⟩
|
||||
|
||||
@[inline] def State.run {σ effs α} (st : σ) : eff (State σ :: effs) α → eff effs (α × σ) :=
|
||||
eff.handleRelayΣ (λ st a, pure (a, st)) (λ β st x k, begin
|
||||
eff.handleRelayΣ (fun st a => pure (a, st)) (fun β st x k => begin
|
||||
cases x,
|
||||
case State.get { exact k st st },
|
||||
case State.put : st' { exact k st' () }
|
||||
|
|
@ -137,12 +137,12 @@ inductive Exception (ε α : Type) : Type
|
|||
|
||||
@[inline] def eff.throw {ε α effs} [member (Exception ε) effs] (ex : ε) : eff effs α := eff.send (Exception.throw ex)
|
||||
@[inline] def eff.catch {ε α effs} [member (Exception ε) effs] (x : eff effs α) (handle : ε → eff effs α) : eff effs α :=
|
||||
x.interpose (Exception ε) pure (λ β x k, match x with Exception.throw e := handle e)
|
||||
x.interpose (Exception ε) pure (fun β x k => match x with Exception.throw e := handle e)
|
||||
instance {ε effs} [member (Exception ε) effs] : MonadExcept ε (eff effs) :=
|
||||
⟨λ α, eff.throw, λ α, eff.catch⟩
|
||||
⟨fun α => eff.throw, fun α => eff.catch⟩
|
||||
|
||||
@[inline] def Exception.run {ε effs α} : eff (Exception ε :: effs) α → eff effs (Except ε α) :=
|
||||
eff.handleRelay (pure ∘ Except.ok) (λ β x k, match x with Exception.throw e := pure (Except.error e))
|
||||
eff.handleRelay (pure ∘ Except.ok) (fun β x k => match x with Exception.throw e := pure (Except.error e))
|
||||
|
||||
|
||||
def eff.run {α : Type} : eff [] α → α
|
||||
|
|
@ -151,25 +151,25 @@ def eff.run {α : Type} : eff [] α → α
|
|||
def eff.runM {α : Type} {m} [Monad m] : eff [m] α → m α
|
||||
| (eff.pure a) := pure a
|
||||
| (eff.impure u k) := match u.decomp with
|
||||
| Sum.inl m := m >>= λ a, eff.runM (k a)
|
||||
| Sum.inl m := m >>= fun a => eff.runM (k a)
|
||||
|
||||
instance (m effs) [member m effs] : HasMonadLift m (eff effs) :=
|
||||
⟨λ α, eff.send⟩
|
||||
⟨fun α => eff.send⟩
|
||||
|
||||
section examples
|
||||
|
||||
-- from http://okmij.org/ftp/Haskell/extensible/EffDynCatch.hs
|
||||
|
||||
@[inline] def IO.try {α} : IO α → IO (Except IO.error α) :=
|
||||
λ x, IO.catch (Except.ok <$> x) (pure ∘ Except.error)
|
||||
fun x => IO.catch (Except.ok <$> x) (pure ∘ Except.error)
|
||||
|
||||
instance : HasRepr IO.error :=
|
||||
⟨λ e, match e with
|
||||
⟨fun e => match e with
|
||||
| IO.error.sys n := "IO.error.sys " ++ repr n
|
||||
| IO.error.other s := "IO.error.other " ++ repr s⟩
|
||||
|
||||
@[inline] def eff.catchIO {effs α} [member IO effs] (x : eff effs α) (catch : IO.error → eff effs α) : eff effs α :=
|
||||
x.interpose IO pure (λ β x k, do ex ← monadLift x.try;
|
||||
x.interpose IO pure (fun β x k => do ex ← monadLift x.try;
|
||||
match ex with
|
||||
| Except.ok b := k b
|
||||
| Except.error e := catch e)
|
||||
|
|
@ -184,11 +184,11 @@ eff.catchIO (Except.ok <$> x) (pure ∘ Except.error)
|
|||
|
||||
-- handle IO exceptions before State
|
||||
def test1 :=
|
||||
let tf : Bool → eff [IO] _ := λ (x : Bool), Reader.run x $ State.run ([] : List String) $ eff.tryIo $
|
||||
do modify (λ xs, "begin"::xs);
|
||||
let tf : Bool → eff [IO] _ := fun (x : Bool) => Reader.run x $ State.run ([] : List String) $ eff.tryIo $
|
||||
do modify (fun xs => "begin"::xs);
|
||||
x ← read;
|
||||
r ← monadLift $ exfn x;
|
||||
modify (λ xs, "end"::xs);
|
||||
modify (fun xs => "end"::xs);
|
||||
pure r in
|
||||
do repr <$> eff.runM (tf tt) >>= IO.println;
|
||||
repr <$> eff.runM (tf ff) >>= IO.println
|
||||
|
|
@ -197,11 +197,11 @@ def test1 :=
|
|||
|
||||
-- handle IO exceptions after State
|
||||
def test2 :=
|
||||
let tf : Bool → eff [IO] _ := λ (x : Bool), Reader.run x $ eff.tryIo $ State.run ([] : List String) $
|
||||
do modify (λ xs, "begin"::xs);
|
||||
let tf : Bool → eff [IO] _ := fun (x : Bool) => Reader.run x $ eff.tryIo $ State.run ([] : List String) $
|
||||
do modify (fun xs => "begin"::xs);
|
||||
x ← read;
|
||||
r ← monadLift $ exfn x;
|
||||
modify (λ xs, "end"::xs);
|
||||
modify (fun xs => "end"::xs);
|
||||
pure r in
|
||||
do repr <$> eff.runM (tf tt) >>= IO.println;
|
||||
repr <$> eff.runM (tf ff) >>= IO.println
|
||||
|
|
|
|||
|
|
@ -87,34 +87,34 @@ meta def eff.bind {α β : Type} {effs : List effect} : eff effs α → (α →
|
|||
| (@eff.impure _ _ β u k) f := eff.impure u (ftcQueue.Node k (ftcQueue.leaf f))
|
||||
|
||||
meta instance (effs) : Monad (eff effs) :=
|
||||
{ pure := λ α, eff.pure,
|
||||
bind := λ α β, eff.bind }
|
||||
{ pure := fun α => eff.pure,
|
||||
bind := fun α β => eff.bind }
|
||||
|
||||
@[inline] meta def eff.send {e : effect} {effs α} [member e effs] : e α → eff effs α :=
|
||||
λ x, eff.impure (union.inj x) (ftcQueue.leaf pure)
|
||||
fun x => eff.impure (union.inj x) (ftcQueue.leaf pure)
|
||||
|
||||
@[inline] meta def eff.handleRelay {e : effect} {effs α β} (ret : β → eff effs α)
|
||||
(h : ∀ {β}, e β → (β → eff effs α) → eff effs α) : eff (e :: effs) β → eff effs α
|
||||
| (eff.pure a) := ret a
|
||||
| (@eff.impure _ _ γ u k) := match u.decomp with
|
||||
| Sum.inl e := h e (λ c, eff.handleRelay (arrs.apply k c))
|
||||
| Sum.inr u := eff.impure u (ftcQueue.leaf (λ c, eff.handleRelay (arrs.apply k c)))
|
||||
| Sum.inl e := h e (fun c => eff.handleRelay (arrs.apply k c))
|
||||
| Sum.inr u := eff.impure u (ftcQueue.leaf (fun c => eff.handleRelay (arrs.apply k c)))
|
||||
|
||||
|
||||
@[inline] meta def eff.handleRelayΣ {e : effect} {effs α β} {σ : Type} (ret : σ → β → eff effs α)
|
||||
(h : ∀ {β}, σ → e β → (σ → β → eff effs α) → eff effs α) : σ → eff (e :: effs) β → eff effs α
|
||||
| st (eff.pure a) := ret st a
|
||||
| st (@eff.impure _ _ γ u k) := match u.decomp with
|
||||
| Sum.inl e := h st e (λ st c, eff.handleRelayΣ st (arrs.apply k c))
|
||||
| Sum.inr u := eff.impure u (ftcQueue.leaf (λ c, eff.handleRelayΣ st (arrs.apply k c)))
|
||||
| Sum.inl e := h st e (fun st c => eff.handleRelayΣ st (arrs.apply k c))
|
||||
| Sum.inr u := eff.impure u (ftcQueue.leaf (fun c => eff.handleRelayΣ st (arrs.apply k c)))
|
||||
|
||||
|
||||
@[inline] meta def eff.interpose {e : effect} {effs α β} [member e effs] (ret : β → eff effs α)
|
||||
(h : ∀ {β}, e β → (β → eff effs α) → eff effs α) : eff effs β → eff effs α
|
||||
| (eff.pure a) := ret a
|
||||
| (@eff.impure _ _ γ u k) := match u.prj e with
|
||||
| some e := h e (λ c, eff.interpose (arrs.apply k c))
|
||||
| none := eff.impure u (ftcQueue.leaf (λ c, eff.interpose (arrs.apply k c)))
|
||||
| some e := h e (fun c => eff.interpose (arrs.apply k c))
|
||||
| none := eff.impure u (ftcQueue.leaf (fun c => eff.interpose (arrs.apply k c)))
|
||||
|
||||
|
||||
inductive Reader (ρ : Type) : Type → Type
|
||||
|
|
@ -124,7 +124,7 @@ inductive Reader (ρ : Type) : Type → Type
|
|||
meta instance {ρ effs} [member (Reader ρ) effs] : MonadReader ρ (eff effs) := ⟨eff.read⟩
|
||||
|
||||
@[inline] meta def Reader.run {ρ effs α} (env : ρ) : eff (Reader ρ :: effs) α → eff effs α :=
|
||||
eff.handleRelay pure (λ β x k, by cases x; exact k env)
|
||||
eff.handleRelay pure (fun β x k => by cases x; exact k env)
|
||||
|
||||
|
||||
inductive State (σ : Type) : Type → Type
|
||||
|
|
@ -134,13 +134,13 @@ inductive State (σ : Type) : Type → Type
|
|||
@[inline] meta def eff.get {σ effs} [member (State σ) effs] : eff effs σ := eff.send State.get
|
||||
@[inline] meta def eff.put {σ effs} [member (State σ) effs] (s : σ) : eff effs Unit := eff.send (State.put s)
|
||||
meta instance {σ effs} [member (State σ) effs] : MonadState σ (eff effs) :=
|
||||
⟨λ α x, do st ← eff.get;
|
||||
⟨fun α x => do st ← eff.get;
|
||||
let ⟨a, s'⟩ := x.run st;
|
||||
eff.put s';
|
||||
pure a⟩
|
||||
|
||||
meta def State.run {σ effs α} (st : σ) : eff (State σ :: effs) α → eff effs (α × σ) :=
|
||||
eff.handleRelayΣ (λ st a, pure (a, st)) (λ β st x k, begin
|
||||
eff.handleRelayΣ (fun st a => pure (a, st)) (fun β st x k => begin
|
||||
cases x,
|
||||
case State.get { exact k st st },
|
||||
case State.put : st' { exact k st' () }
|
||||
|
|
@ -151,12 +151,12 @@ inductive Exception (ε α : Type) : Type
|
|||
|
||||
@[inline] meta def eff.throw {ε α effs} [member (Exception ε) effs] (ex : ε) : eff effs α := eff.send (Exception.throw ex)
|
||||
@[inline] meta def eff.catch {ε α effs} [member (Exception ε) effs] (x : eff effs α) (handle : ε → eff effs α) : eff effs α :=
|
||||
x.interpose pure (λ β x k, match (x : Exception ε β) with Exception.throw e := handle e)
|
||||
x.interpose pure (fun β x k => match (x : Exception ε β) with Exception.throw e := handle e)
|
||||
meta instance {ε effs} [member (Exception ε) effs] : MonadExcept ε (eff effs) :=
|
||||
⟨λ α, eff.throw, λ α, eff.catch⟩
|
||||
⟨fun α => eff.throw, fun α => eff.catch⟩
|
||||
|
||||
@[inline] meta def Exception.run {ε effs α} : eff (Exception ε :: effs) α → eff effs (Except ε α) :=
|
||||
eff.handleRelay (pure ∘ Except.ok) (λ β x k, match x with Exception.throw e := pure (Except.error e))
|
||||
eff.handleRelay (pure ∘ Except.ok) (fun β x k => match x with Exception.throw e := pure (Except.error e))
|
||||
|
||||
|
||||
meta def eff.run {α : Type} : eff [] α → α
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue