lean4-htt/Lake/Build/Target.lean

161 lines
6.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2021 Mac Malone. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mac Malone
-/
import Lake.Util.Async
import Lake.Build.Trace
open System
namespace Lake
--------------------------------------------------------------------------------
/-! # Active Targets -/
--------------------------------------------------------------------------------
def ActiveTarget.{u,v} (ι : Type u) (k : Type u → Type v) (τ : Type u) :=
k (ι × τ)
namespace ActiveTarget
@[inline] def mk (task : k (ι × τ)) : ActiveTarget ι k τ :=
task
@[inline] def task (target : ActiveTarget ι k τ) : k (ι × τ) :=
target
instance [Inhabited ι] [Inhabited τ] [Pure k] : Inhabited (ActiveTarget ι k τ) :=
⟨mk <| pure default⟩
@[inline] def «opaque» [Functor k] (task : k t) : ActiveTarget PUnit k t :=
mk <| ((), ·) <$> task
@[inline] def nil [NilTrace τ] [Pure k] : ActiveTarget PUnit k τ :=
mk <| pure ((), nilTrace)
@[inline] protected def bindSync [BindSync m n k]
(self : ActiveTarget ι k α) (f : ια → m β) : n (k β) :=
bindSync self fun (i, a) => f i a
@[inline] protected def bindOpaqueSync [BindSync m n k]
(self : ActiveTarget ι k α) (f : α → m β) : n (k β) :=
bindSync self fun (_, a) => f a
@[inline] protected def bindAsync [BindAsync n k]
(self : ActiveTarget ι k α) (f : ια → n (k β)) : n (k β) :=
bindAsync self fun (i, a) => f i a
@[inline] protected def bindOpaqueAsync [BindAsync n k]
(self : ActiveTarget ι k α) (f : α → n (k β)) : n (k β) :=
bindAsync self fun (_, a) => f a
@[inline] def build
[Await k n] [MonadLiftT n m] [Functor m] (self : ActiveTarget ι k τ) : m ι :=
(·.1) <$> liftM (await self.task)
@[inline] def buildOpaque
[Await k n] [MonadLiftT n m] [Functor m] (self : ActiveTarget ι k τ) : m PUnit :=
discard <| liftM (await self.task)
variable [MixTrace τ] [SeqWithAsync n k] [MonadLiftT n m] [Monad m]
def mixOpaqueAsync
(t1 : ActiveTarget α k τ) (t2 : ActiveTarget β k τ) : m (ActiveTarget PUnit k τ) :=
mk <$> liftM (seqWithAsync (fun (_,t) (_,t') => ((), mixTrace t t')) t1 t2)
variable [NilTrace τ] [Monad n] [Pure k]
def collectList (targets : List (ActiveTarget ι k τ)) : m (ActiveTarget (List ι) k τ) := mk <$> do
liftM <| foldLeftListAsync (fun (i,t') (a,t) => (i :: a, mixTrace t t')) ([], nilTrace) targets
def collectArray (targets : Array (ActiveTarget ι k τ)) : m (ActiveTarget (Array ι) k τ) := mk <$> do
liftM <| foldRightArrayAsync (fun (a,t) (i,t') => (a.push i, mixTrace t t')) (#[], nilTrace) targets
variable [Functor k]
def collectOpaqueList (targets : List (ActiveTarget ι k τ)) : m (ActiveTarget PUnit k τ) := «opaque» <$> do
liftM <| foldLeftListAsync (fun (_,t') t => mixTrace t t') nilTrace targets
def collectOpaqueArray (targets : Array (ActiveTarget ι k τ)) : m (ActiveTarget PUnit k τ) := «opaque» <$> do
liftM <| foldRightArrayAsync (fun t (_,t') => mixTrace t t') nilTrace targets
end ActiveTarget
--------------------------------------------------------------------------------
/-! # Inactive Target -/
--------------------------------------------------------------------------------
structure Target.{u,v,w} (ι : Type u) (n : Type v → Type w) (k : Type u → Type v) (τ : Type u) where
task : n (k (ι × τ))
instance [Inhabited ι] [Inhabited τ] [Pure n] [Pure k] : Inhabited (Target ι n k τ) :=
⟨⟨pure (pure default)⟩⟩
namespace Target
@[inline] def active [Pure n] (target : ActiveTarget ι k τ) : Target ι n k τ :=
mk <| pure target
@[inline] def nil [NilTrace τ] [Pure n] [Pure k] : Target PUnit n k τ :=
mk <| pure <| pure <| ((), nilTrace)
@[inline] def activate [Functor n] (self : Target ι n k τ) : n (ActiveTarget ι k τ) :=
(.mk ·) <$> self.task
@[inline] def materializeAsync [Functor n] [Functor k] (self : Target ι n k τ) : n (k τ) :=
((·.2) <$> ·) <$> self.task
def materialize [Await k m'] [MonadLiftT m' m] [MonadLiftT n m] [Functor m] [Bind m] (self : Target ι n k τ) : m τ :=
liftM self.task >>= fun t => (·.2) <$> liftM (await t)
@[inline] protected def bindSync [BindSync m n k] [Bind n]
(self : Target ι n k τ) (f : ι → τ → m β) : n (k β) :=
self.task >>= fun tk => bindSync tk fun (i,t) => f i t
@[inline] protected def bindOpaqueSync
[BindSync m n k] [Bind n] (self : Target ι n k τ) (f : τ → m β) : n (k β) :=
self.task >>= fun tk => bindSync tk fun (_,t) => f t
@[inline] protected def bindAsync
[BindAsync n k] [Bind n] (self : Target ι n k τ) (f : ι → τ → n (k β)) : n (k β) :=
self.task >>= fun tk => bindAsync tk fun (i,t) => f i t
@[inline] protected def bindOpaqueAsync
[BindAsync n k] [Bind n] (self : Target ι n k τ) (f : τ → n (k β)) : n (k β) :=
self.task >>= fun tk => bindAsync tk fun (_,t) => f t
def mixOpaqueAsync
[MixTrace τ] [SeqWithAsync n k] [Functor k] [Monad n]
(t1 : Target α n k τ) (t2 : Target β n k τ) : Target PUnit n k τ := mk do
let tk1 ← t1.materializeAsync
let tk2 ← t2.materializeAsync
((fun t => ((),t)) <$> ·) <$> seqWithAsync mixTrace tk1 tk2
section
variable [NilTrace τ] [MixTrace τ]
variable [SeqWithAsync n' k] [Monad n'] [MonadLiftT n' n] [Monad n] [Pure k] [Functor k]
def materializeListAsync (targets : List (Target ι n k τ)) : n (k τ) := do
liftM <| foldRightListAsync mixTrace nilTrace (← targets.mapM (·.materializeAsync))
def materializeArrayAsync (targets : Array (Target ι n k τ)) : n (k τ) := do
liftM <| foldRightArrayAsync mixTrace nilTrace (← targets.mapM (·.materializeAsync))
def collectList (targets : List (Target ι n k τ)) : Target (List ι) n k τ := mk do
let tasks ← targets.mapM (·.task)
let f := fun (i,t') (a,t) => (i :: a, mixTrace t t')
liftM <| foldLeftListAsync f ([], nilTrace) tasks
def collectArray (targets : Array (Target ι n k τ)) : Target (Array ι) n k τ := mk do
let tasks ← targets.mapM (·.task)
let f := fun (a,t) (i,t') => (a.push i, mixTrace t t')
liftM <| foldRightArrayAsync f (#[], nilTrace) tasks
def collectOpaqueList (targets : List (Target ι n k τ)) : Target PUnit n k τ :=
mk <| ((fun t => ((), t)) <$> ·) <$> materializeListAsync targets
def collectOpaqueArray (targets : Array (Target ι n k τ)) : Target PUnit n k τ :=
mk <| ((fun t => ((), t)) <$> ·) <$> materializeArrayAsync targets
end
end Target