lambda-uc-0.1.0.0
Safe HaskellSafe
LanguageGHC2021

LambdaUC.Syntax.Async.Eval.Internal

Synopsis

Execution Implementation

These are utility functions that are used by runExec to evaluate an exection.

The fork_, swap_ and link_ correspond one-to-one to the constructors of Exec. And escapeSyncT evaluates a concurrent algorithm that has all of its ports bound as a local algorithm.

fork_ #

Arguments

:: forall st st' ach ach' bef bef' aft aft' a a'. ForkPremiseD bef bef' aft aft' a a'

Proof that this combination of indices and return values is valid

-> KnownLenD ach

Depdendent length of free ports list in left branch

-> AsyncT ach bef aft a

Left branch of the fork_

-> AsyncT ach' bef' aft' a'

Right branch of the fork_

-> AsyncT (Concat ach ach') (ForkIndexOr bef bef') (ForkIndexOr aft aft') (ChooseRet aft aft' a a') 

Run two processes in parallel exposing the free ports of both of them.

The typeclass constaint Forkable here ensures that:

  1. No more than one of forked processes expects to finish in NextSend.
  2. Only the process that finishes in NextSend is allowed to produce a (non-Void) result.

The resulting action that implements the fork_ starts in NextSend if one of the forked actions started in NextSend. Similarly, it finishes in NextSend if one of the forked two finishes in NextSend. (Implemented with ForkIndexOr.)

The return value of the fork_ is the same as return value of process that finishes in NextSend. If both finish in NextRecv, then fork_'s return value is Void.

swap_ #

Arguments

:: KnownIndex bef 
=> ListSplitD l p (f : l')

Proof of l == p ++ (f:l')

-> ListSplitD l' p' (s : rest)

Proof of l' == p' ++ (s:rest)

-> AsyncT l bef aft a 
-> AsyncT (Concat p (s : Concat p' (f : rest))) bef aft a 

Swap two free ports.

We go from an action where free ports are p ++ [f] ++ p' ++ [s] ++ rest to p ++ [s] ++ p' ++ [f] ++ rest. In other words, the elemens f and s are swapped.

The ListSplitD arguments can often be derived automatically if p p' and rest are fully known.

link_ #

Arguments

:: KnownIndex bef 
=> MayOnlyReturnAfterRecvD aft a 
-> ListSplitD l p ((x :> y) : l')

Proof of l == p ++ [(x, y)] ++ l'

-> ListSplitD l' p' ((y :> x) : rest)

Proof of l' == p' ++ [(y, x)] ++ rest

-> AsyncT l bef aft a

Exectuion where we want to link_ the ports

-> AsyncT (Concat p (Concat p' rest)) bef aft a 

Link two adjacent free ports with each other. This binds them and removes from the free list.

spawnOnDemand_ :: forall l r ports. ConstrAllD Ord l -> ConstrAllD Ord r -> KnownHPPortsD ports -> KnownLenD l -> KnownLenD r -> (HListPair l r -> AsyncT ports NextRecv NextRecv Void) -> AsyncT (MapConcat2 l r ports) NextRecv NextRecv Void #

Unsafe

permPorts :: KnownIndex bef => (forall p. InList l p -> InList l' p) -> (forall p. InList l' p -> InList l p) -> AsyncT l bef aft a -> AsyncT l' bef aft a #

Reorders the open the free ports.

The permPorts f g should only be called with f . g = id. This is not verified by compiler, should be checked manually.

For a safe alternative, see swap_. That one is guaranteed to only permute ports and never cause bad behaviors.

Helper functions and types

class InitStatusIndexRet s i res where #

Instances

Instances details
(s ~ 'InitAbsent, res ~ Void) => InitStatusIndexRet s 'NextRecv res # 
Instance details

Defined in LambdaUC.Syntax.Async.Eval.Internal

s ~ 'InitPresent res => InitStatusIndexRet s 'NextSend res # 
Instance details

Defined in LambdaUC.Syntax.Async.Eval.Internal

class InitStatusComp st st' where #

Instances

Instances details
KnownInitStatus st' => InitStatusComp 'InitAbsent st' # 
Instance details

Defined in LambdaUC.Syntax.Async.Eval.Internal

st' ~ 'InitAbsent => InitStatusComp ('InitPresent res) st' # 
Instance details

Defined in LambdaUC.Syntax.Async.Eval.Internal

type family ToInitStatus (i :: Index) (a :: Type) where ... #

type family InitStatusRes (st :: InitStatus) where ... #

data ForkPremiseD bef bef' aft aft' a a' #

Constructors

ForkPremiseD 

Fields

getForkPremiseD :: (ForkIndexComp bef bef', ForkIndexComp aft aft', MayOnlyReturnAfterRecv aft a, MayOnlyReturnAfterRecv aft' a') => ForkPremiseD bef bef' aft aft' a a' #

class MayOnlyReturnAfterRecv i a where #

Methods

getMayOnlyReturnAfterRecvPrf :: MayOnlyReturnAfterRecvD i a #

Instances

Instances details
MayOnlyReturnAfterRecv 'NextRecv Void # 
Instance details

Defined in LambdaUC.Syntax.Async.Eval.Internal

Methods

getMayOnlyReturnAfterRecvPrf :: MayOnlyReturnAfterRecvD 'NextRecv Void #

MayOnlyReturnAfterRecv 'NextSend a # 
Instance details

Defined in LambdaUC.Syntax.Async.Eval.Internal

Methods

getMayOnlyReturnAfterRecvPrf :: MayOnlyReturnAfterRecvD 'NextSend a #

class ForkIndexComp befFst befSnd where #

Methods

getForkIndexComp :: ForkIndexCompD befFst befSnd #

Instances

Instances details
KnownIndex i => ForkIndexComp 'NextRecv i # 
Instance details

Defined in LambdaUC.Syntax.Async.Eval.Internal

i ~ 'NextRecv => ForkIndexComp 'NextSend i # 
Instance details

Defined in LambdaUC.Syntax.Async.Eval.Internal

type family ForkIndexOr bef bef' where ... #

type family ChooseRet i i' a a' where ... #

Equations

ChooseRet NextRecv NextRecv _ _ = Void 
ChooseRet NextSend _ a _ = a 
ChooseRet _ NextSend _ a' = a'