lambda-uc-0.1.0.0
Safe HaskellSafe
LanguageGHC2021

LambdaUC.Syntax.Sync.Eval

Synopsis

Execution with Oracle

The following are definitions related to running an algorithm with an given oracle. The runWithOracles executes an algorithm with an oracle, while OracleCaller and OracleWrapper are convenient type synonyms for the interactive algorithms that define the oracle caller and oracle respectively.

The oracle is expected to terminate and produce the result s right after receiving special request OracleReqHalt, but not before then. If the oracle violates this condition, the runWithOracles fails with mzero. To differentiate between service OracleReqHalt and the regular queries from the algorithm, we wrap the latter in OracleReq type.

runWithOracles #

Arguments

:: forall m (down :: [Port]) (rets :: [Type]) a. SameLen down rets 
=> OracleCaller down a

The oracle caller algorithm

-> HList2 OracleWrapper down rets

The implementations of oracles available to caller

-> MaybeT PrAlgo (a, HList Identity rets)

The outputs of caller and oracle. Fails with mzero if the oracle terminates before time or doesn't terminate when requested

Given main algorithm top and a list of oracle algorithms bot, `runWithOracles top bot` will run them together (top querying any oracle the oracles in bot) and return their results.

The top returns its result directly when terminating, then a special OracleReqHalt message is sent to all of bot to ask them to terminate and return their results.

We throw a mzero error in case an oracle does not follow the termination condition: terminates before receiving OracleReqHalt or tries to respond to OracleReqHalt instead of terminating.

Note that runWithOracles passes all the messages between the running interactive algorithms, therefore its result is a non-interactive algorithm.

type OracleCaller down = SyncT down PrAlgo #

An algorithm with no parent and with access to child oracles given by down.

newtype OracleWrapper (up :: Port) (ret :: Type) #

Version of Oracle that's wrapped in newtype, convenient for use with HList2.

Constructors

OracleWrapper 

Fields

type Oracle (up :: Port) = AsyncT '[PortRxType up :> OracleReq (PortTxType up)] NextRecv NextSend #

An algorithm serving oracle calls from parent, but not having access to any oracles of its own.

data OracleReq a #

Constructors

OracleReqHalt 
OracleReq a 

runWithOracles1 :: OracleCaller '[x :> y] a -> OracleWrapper (x :> y) b -> MaybeT PrAlgo (a, b) #

Version of runWithOracles that accepts only one oracle

runWithOracles2 :: OracleCaller '[x :> y, x' :> y'] a -> OracleWrapper (x :> y) b -> OracleWrapper (x' :> y') b' -> MaybeT PrAlgo (a, b, b') #

Version of runWithOracles that accepts two oracles