!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl m n o p q r s t u v w x y z { | } ~  See withCheck. LA helper type for describing a more detailed result of a CHP test. You can / construct these values manually, or using the '(=*=)' operator. <A wrapper around the CHP type that supports some QuickCheck  instances.  See  and . Turns a CHP program into a  for use with  instances. Equivalent to qcCHP' . runCHP_CSPTrace. ;Takes the command that runs a CHP program and gives back a   item for use with  instances. You use this function like:   qcCHP' (runCHP_CSPTrace p) To test process p; with a CSP trace if it fails. To turn off the display of ! tracing when a test fails, use:  qcCHP' (runCHP_TraceOff p) NTests a process that takes a single input and produces a single output, using  QuickCheck. LThe first parameter is a pure function that takes the input to the process, N the output the process gave back, and indicates whether this is okay (True = N test pass, False = test fail). The second parameter is the process to test, M and the third parameter is the thing to use to generate the inputs (passing  arbitrary  is the simplest thing to do). #Here are a couple of example uses:  4 propCHPInOut (==) Common.id (arbitrary :: Gen Int)  Q propCHPInOut (const $ (< 0)) (Common.map (negate . abs)) (arbitrary :: Gen Int) QThe test starts the process afresh each time, and shuts it down after the single M output has been produced (by poisoning both its channels). Any poison from T the process being tested after it has produced its output is consequently ignored, F but poison instead of producing an output will cause a test failure. N If the process does not produce an output or poison (for example if you test D something like the Common.filter process), the test will deadlock. JTakes a CHP program that returns a Bool (True = test passed, False = test * failed) and forms it into an HUnit test. ONote that if the program exits with poison, this is counted as a test failure. MChecks if two things are equal; passes the test if they are, otherwise fails ; and gives an error that shows the two things in question. Like / but allows you to return the more descriptive  ! type, rather than a plain Bool. TA helper function that allows you to create CHP tests in an assertion style, either % for use with HUnit or QuickCheck 2. OAny poison thrown by the first argument (the left-hand side when this function N is used infix) is trapped and ignored. Poison thrown by the second argument E (the right-hand side when used infix) is counted as a test failure. FAs an example, imagine that you have a process that should repeatedly $ output the same value (42), called myProc". There are several ways to test I this, but for the purposes of illustration we will start by testing the  first two values:   myTest :: Test  myTest = testCHP' $ do  c <- oneToOneChannel  myProc (writer c) ; `withCheck` do x0 <- liftCHP $ readChannel (reader c) K assertCHPEqual (poison (reader c)) "First value" 42 x0 ; x1 <- liftCHP $ readChannel (reader c) 9 poison (reader c) -- Shutdown myProc 9 assertCHPEqual' "Second value" 42 x1 NThis demonstrates the typical pattern: a do block with some initialisation to N begin with (creating channels, enrolling on barriers), then a withCheck call O with the thing you want to test on the left-hand side, and the part doing the W testing with the asserts on the right-hand side. Most CHP actions must be surrounded  by 4, and assertions can then be made about the values. MPoison is used twice in our example. The assertCHPEqual function takes as a L first argument the command to execute if the assertion fails. The problem M is that if the assertion fails, the right-hand side will finish. But it is M composed in parallel with the left-hand side, which does not know to finish M (deadlock!). Thus we must pass a command to execute if the assertion fails D that will shutdown the right-hand side. The second assertion doesn't need K this, because by the time we make the assertion, we have already inserted  the poison. Don'9t forget that you must poison to shut down the left-hand F side if your test is successful or else you will again get deadlock. OA better way to test this process is of course to read in a much larger number : of samples and check they are all the same, for example:  myTest :: Test  myTest = testCHP' $ do  c <- oneToOneChannel  myProc (writer c) M `withCheck` do xs <- liftCHP $ replicateM 1000 $ readChannel (reader c) 9 poison (reader c) -- Shutdown myProc I assertCHPEqual' "1000 values" xs (replicate 1000 42) LChecks that the given Bool is True. If it is, the assertion passes and the N test continues. If it is False, the given command is run (which should shut O down the left-hand side of withCheck) and the test finishes, failing with the  given String. KChecks that the given values are equal (first is the expected value of the U test, second is the actual value). If they are equal, the assertion passes and the U test continues. If they are not equal, the given command is run (which should shut O down the left-hand side of withCheck) and the test finishes, failing with the F a message formed of the given String, and describing the two values. Like  ; but issues no shutdown command. You should only use this V function if you are sure that the left-hand side of withCheck has already completed. Like  ; but issues no shutdown command. You should only use this V function if you are sure that the left-hand side of withCheck has already completed. NTests a process that takes a single input and produces a single output, using  HUnit. LThe first parameter is a pure function that takes the input to the process, N the output the process gave back, and indicates whether this is okay (True = N test pass, False = test fail). The second parameter is the process to test, > and the third parameter is the input to send to the process. OThe intention is that you will either create several tests with the same first Q two parameters or use a const function as the first parameter. So for example, E here is how you might test the identity process with several tests:  ) let check = testCHPInOut (==) Common.id 1 in TestList [check 0, check 3, check undefined] AWhereas here is how you could test a slightly different process:  F let check = testCHPInOut (const $ (< 0)) (Common.map (negate . abs)) ! in TestList $ map check [-5..5] QThe test starts the process afresh each time, and shuts it down after the single M output has been produced (by poisoning both its channels). Any poison from T the process being tested after it has produced its output is consequently ignored, F but poison instead of producing an output will cause a test failure. N If the process does not produce an output or poison (for example if you test D something like the Common.filter process), the test will deadlock.      IA set of channels to be given to the process to run, containing channels  for stdin, stdout and stderr. JA function for running the given CHP process that wants console channels. N When your program finishes, the console channels are automatically poisoned,  but it'Ds good practice to poison them yourself when you finish. Only ever K run one of these processes at a time, or undefined behaviour will result. RWhen using this process, due to the way that the console handlers are terminated, T you may sometimes see a notice that a thread was killed. This is normal behaviour  (unfortunately).  LThis data represents a behaviour (potentially repeated) that will result in  returning a value of type a. See ! for more details. HOffers the given behaviour, and when it occurs, ends the entire call to !. M Returns Just the result if the behaviour happens, otherwise gives Nothing. IOffers the given behaviour, and when it occurs, does not offer it again. L Returns Just the result if the behaviour happens, otherwise gives Nothing.   is different to + because the latter terminates the call to ! ) regardless of other behaviours, whereas  does not terminate the call to !,  it just won'&t be offered again during the call to !. Thus if you only  offer some  items without any , then after all the  events + have happened, the process will deadlock. once m% can be thought of as a shortcut for  listToMaybe  $ upTo1 m MOffers the given behaviour up to the given number of times, returning a list 0 of the results (in chronological order). Like , when the limit is reached,  the call to !, is not terminated, so you still require an . >Repeatedly offers the given behaviour until the outer call to ! is terminated  by an D event. A list is returned (in chronological order) of the results ' of each occurrence of the behaviour.  repeatedly is like an unbounded upTo. Like :, but discards the output. Useful if the event is likely  to occur a lot, and you don't need the results. Like !, but allows some state (of type a) to be passed from one G subsequent call to another, as well as generating the results of type b. N To begin with the function (first parameter) will be called with the initial R state (second parameter). If chosen, it will return the new state, and a result R to be accumulated into the list. The second call to the function will be passed M the new state, to then return the even newer state and a second result, and  so on. PIf you want to use this with the StateT monad transformer from the mtl library,  you can call: : repeatedlyRecurse (runStateT myStateAction) initialState  where % myStateAction :: StateT s CHP a  initialState :: s Like -, but does not accumulate a list of results. PIf you want to use this with the StateT monad transformer from the mtl library,  you can call: ; repeatedlyRecurse (execStateT myStateAction) initialState  where % myStateAction :: StateT s CHP a  initialState :: s HOffers one behaviour alongside another, combining their semantics. See !. <This operation is semantically associative and commutative. HOffers one behaviour alongside another, combining their semantics. See !.  Unlike ), discards the output of the behaviours. /This operation is associative and commutative. !+Offers the given behaviour until finished.  For example,  / offer $ repeatedly p `alongside` repeatedly q ?will repeatedly offer p and q without ever terminating. This:  E offer $ repeatedly p `alongside` repeatedly q `alongside` endWhen r Pwill offer p repeatedly and q repeatedly and r, until r happens, at which point  the behaviour will end.  This:  & offer $ once p `alongside` endWhen q Lwill offer p and q; if p happens first it will wait for q, but if q happens  first it will finish. This:  < offer $ once p `alongside` endWhen q `alongside` endWhen r Opermits p to happen at most once, while either of q or r happening will finish  the call. MAll sorts of combinations are possible, but it is important to note that you  need at least one 4 event if you ever intend the call to finish. Some  laws involving !- (ignoring the types and return values) are:  # offer (repeatedly p) == forever p 8 offer (once p) == p >> stop -- i.e. it does not finish ! offer (endWhen q) == Just <$> q 4 offer (endWhen p `alongside` endWhen q) == p <-> q 8 offer (once p `alongside` endWhen q) == (p >> q) <-> q Most other uses of ! and " do not reduce down to simple CHP 0 programs, which is of course their attraction. "QOffers all the given behaviours together, and gives back a list of the outcomes.  This is roughly a shorthand for offer . foldl1 alongside, except that if you M pass the empty list, you simply get the empty list returned (rather than an  error)  !" !"   !"#NA pair of channels. The main use of this type is with the Connectable class, R as it allows you to wire together two processes that take the exact same channel  pair, e.g. both are of type 0ChannelPair (Chanin Int) (Chanout Int) -> CHP () . With the A normal Connectable pair instances, one would need to be of type  (Chanin Int,  Chanout Int) -> CHP (), and the other of type (Chanout Int, Chanin Int) ->  CHP (). $HIndicates that its two parameters can be joined together automatically. Rather than use %3 directly, you will want to use the operators such  as '( =)'C. There are different forms of this operator for in the middle of N a pipeline (where you still need further parameters to each process), and at  the ends. See also 0 and 1. %2Runs the given code with the two items connected. &Like $!, but allows an extra parameter. MThe API (and name) for this is still in flux, so do not rely on it just yet. '(2Runs the given code with the two items connected. )Like %B, but provides the process a list of items of the specified size,  and runs it. *Like ) but ignores the results. +BJoins together the given two processes and runs them in parallel. ,BJoins together the given two processes and runs them in parallel. -BJoins together the given two processes and runs them in parallel. .BJoins together the given two processes and runs them in parallel. /Like '( =)' but with & 0Like foldl1 ( =):; connects a pipeline of processes together. If the list W is empty, it returns a process that ignores both its arguments and returns instantly. 1HConnects the given beginning process, the list of middle processes, and M the end process into a pipeline and runs them all in parallel. If the list : is empty, it connects the beginning directly to the end. 2Like 04 but also connects the last process into the first. 0 If the list is empty, it returns immediately. #$%&'()*+,-./012$%,.-+012)*#&'(/#$%%&'('()*+,-./0123+EightWay is simply a synonym for a pair of ;: and 54. 4LA data type representing four-way diagonal connectivity for a process, with ? channels above-left, below-right, above-right and below-left. 56789:LA data type representing four-way connectivity for a process, with channels ) to the left and right, above and below. ;<=>?@PWires the given grid of processes (that require four-way connectivity) together E into a wrapped around grid (a torus) and runs them all in parallel. NThe parameter is a list of rows, and should be rectangular (i.e. all the rows N should be the same length). If not, an error will result. The return value 2 is guaranteed to be the same shape as the input. HIt is worth remembering that if you have only one row or one column (or I both), processes can be connected to themselves, so make sure that if a M process is connected to itself (e.g. its left channel connects to its right ' channel), it is coded such that it won',t deadlock -- or if needed, checks for this  possibility using 1. Processes may also be connected to each other 3 multiple times -- in a two-wide grid, each process's left channel connects to  the same process as its right. ALike @! but discards the return values. BLike @& but provides eight-way connectivity.  The note on @/ about processes being connected to themselves I applies here too -- as does the note about processes being connected to ; each other multiple times. If you have one row, a process's left, M above-left and below-left channels all connect to the same process. If you " have a two-by-two grid, a process'(s four diagonal channels all connect to  the same process. CLike B but discards the output. 3456789:;<=>?@ABC:;<=>?@A4567893BC345678956789:;<=>?;<=>?@ABC DPA monad for composing together CHP processes in cross-cutting ways; e.g. wiring N together a list of processes into a pipeline, but also enrolling them all on  a barrier. ESee F and G FKGiven a list of CHP processes composed using the Composed monad, runs them * as a parallel bunch of CHP results (with ) and returns the results. GLike F but discards the results (uses ). HLike D, this takes a barrier and a process wanting a barrier, and enrolls - it for the duration, but operates using the D monad. I Given an  item (such as a ), and a list of processes, ; composes them by enrolling them all on the given barrier. JLike % but operates in the D monad. KJWires a list of processes into a pipeline that takes the two channels for F the ends of the pipeline and returns the list of wired-up processes. LM4Connects together a list of processes into a cycle. NLike wrappedGridFour , but in the D monad. DEFGHIJKLMN DEEFGHIJKLMN DEEFGHIJKLMNOLForever forwards the value onwards, unchanged. Adding this to your process 1 network effectively adds a single-place buffer. P-Forever forwards the value onwards. This is  like OB but does not add any buffering to your network, and its presence - is indetectable to the process either side. ,extId is a unit of the associative operator !Control.Concurrent.CHP.Utils.|->|. Q8A process that waits for an input, then sends it out on all its output T channels (in order) during an extended rendezvous. This is often used to send the L output on to both the normal recipient (without introducing buffering) and N also to a listener process that wants to examine the value. If the listener L process is first in the list, and does not take the input immediately, the I value will not be sent to the other recipients until it does. The name J of the process derives from the notion of a wire-tap, since the listener N is hidden from the other processes (it does not visibly change the semantics M for them -- except when the readers of the channels are offering a choice). RBSends out a single value first (the prefix) then behaves like id. S8Discards the first value it receives then act likes id. TBForever reads in a value, and then sends out its successor (using ). UGReads in a value, and sends it out in parallel on all the given output  channels. VOForever reads in a value, transforms it using the given function, and sends it I out again. Note that the transformation is not applied strictly, so don't I assume that this process will actually perform the computation. If you & require a strict transformation, use W. WLike V<, but applies the transformation strictly before sending on  the value. XHForever reads in a value, and then based on applying the given function G either discards it (if the function returns False) or sends it on (if  the function returns True). YStreams all items in a Data.Traversable.Traversable container out  in the order given by Data.Traversable.mapM on the output channel (one at  a time). Lists, , and  Data.Set.Set are all instances  of Data.Traversable.Traversable!, so this can be used for all of  those. ZCForever waits for input from one of its many channels and sends it " out again on the output channel. [HSends out the specified value on the given channel the specified number  of times, then finishes. \GForever sends out the same value on the given channel, until poisoned. @ Similar to the white-hole processes in some other frameworks. ]IForever reads values from the channel and discards them, until poisoned. @ Similar to the black-hole processes in some other frameworks. ^LFor the duration of the given process, acts as a consume process, but stops N when the given process stops. Note that there could be a timing issue where F extra inputs are consumed at the end of the lifetime of the process. N Note also that while poison from the given process will be propagated on the U consumption channel, there is no mechanism to propagate poison from the consumption ! channel into the given process. _KForever reads a value from both its input channels in parallel, then joins Q the two values using the given function and sends them out again. For example,   join (,) c d will pair the values read from c and d and send out the % pair on the output channel, whereas join (&&) will send out the conjunction  of two boolean values,  join (==)) will read two values and output whether  they are equal or not, etc. `JForever reads a value from all its input channels in parallel, then joins U the values into a list in the same order as the channels, and sends them out again. aHForever reads a pair from its input channel, then in parallel sends out @ the first and second parts of the pair on its output channels. b.A sorter process. When it receives its first Just x data item, it keeps L it. When it receieves a second, it keeps the lowest of the two, and sends L out the other one. When it receives Nothing, it sends out its data value, Q then sends Nothing too. The overall effect when chaining these things together I is a sorting pump. You inject all the values with Just, then send in a ; single Nothing to get the results out (in reverse order). cFLike sorter, but with a custom comparison method. You should pass in  the equivalent of less-than: (<). dHA shared variable process. Given an initial value and two channels, it F continually offers to output its current value or read in a new one. eHA shared variable process. The same as valueStore, but initially waits N to read its starting value before then offering to either output its current  value or read in a new one. fMContinually waits for a specific time on the given clock, each time applying O the function to work out the next specific time to wait for. The most common ( thing to pass is Prelude.succ or (+1). OPQRSTUVWXYZ[\]^_`abcdefOPQRSTUVWXYZ[\]^_`abcdefOPQRSTUVWXYZ[\]^_`abcdefgHActs like a limited capacity FIFO buffer of the given size. When it is E full it accepts no input, and when it is empty it offers no output. hIActs like a FIFO buffer with unlimited capacity. Use with caution; make O sure you do not let the buffer grow so large that it eats up all your memory. C When it is empty, it offers no output. It always accepts input. iAActs like a FIFO buffer with unlimited capacity, but accumulates M sequential inputs into a list which it offers in a single output. Use with L caution; make sure you do not let the buffer grow so large that it eats up J all your memory. When it is empty, it offers the empty list. It always J accepts input. Once it has sent out a value (or values) it removes them  from its internal storage. jJActs like a FIFO buffer of limited capacity, except that when it is full, W it always accepts input and discards it. When it is empty, it does not offer output. kJActs like a FIFO buffer of limited capacity, except that when it is full, M it always accepts input and pushes out the oldest item in the buffer. When ( it is empty, it does not offer output. ghijkghijkghijk l The type that is an instance of  for process pipelines. See m. mGiven a l (formed using its  instance) and I the channels to plug into the ends of the pipeline, returns the process  representing the pipeline. FThe pipeline will run forever (until poisoned) and you must run it in L parallel to whatever is feeding it the inputs and reading off the outputs. L Imagine that you want a process pipeline that takes in a pair of numbers, F doubles the first and adds one to the second. You could encode this  in an arrow using:  % runPipeline (arr (*2) *** arr (+1)) EArrows are more useful where you already have processes written that M process data and you want to easily wire them together. The arrow notation L is probably easier for doing that than declaring all the channels yourself ' and composing everything in parallel. n%ProcessPipelineLabel is a version of l that allows the processes O to be labelled, and thus in turn for the channels connecting the processes to O be automatically labelled. ProcessPipelineLabel is not an instance of Arrow, P but it does have a lot of similarly named functions for working with it. This O awkwardness is due to the extra Show constraints on the connectors that allow  the arrow' s contents to appear in traces.  If you don't use traces, use l". If you do use traces, and want O to have better labels on the process and values used in your arrows, consider $ switching to ProcessPipelineLabel. oLike m but for n pLike w3, but allows the process to be labelled. The same  warnings as w apply. qLike  for l), but allows the process to be labelled. rLike x), but allows the process to be labelled. sThe '(>>>)' arrow combinator, for n. tThe '(<<<)' arrow combinator, for n. uThe '(&&&)' arrow combinator, for n. vThe '(***)' arrow combinator, for n. wFAdds a wrapper that forms this process into the right data type to be  part of an arrow. DAny process you apply this to should produce exactly one output per L input, or else you will find odd behaviour resulting (including deadlock).  So for example, don't use arrowProcess ($Control.Concurrent.CHP.Common.filter  ...) or  arrowProcess $Control.Concurrent.CHP.Common.stream inside any arrow combinators  other than >>> and <<<. xQLike the arr function of the ProcessPipeline arrow instance, but fully evaluates U the result before sending it. If you are building process pipelines with arrows to M try and get some parallel speed-up, you should try this function instead of  arr itself. lmnopqrstuvwxlmmwxnoopqrstuv lmmnoopqrstuvwx yA receive action. See |. Note that it is poisonable. zA send action. See {. Note that it is poisonable. {JSends a data item using the given sendAction. Whether this operation can  be used in a choice (see 0) is entirely dependent on whether the original 0 action could be used in an alt. For all of CHP's channels, this is true, but 1 for your own custom send actions, probably not. |MReceives a data item using the given recvAction. Whether this operation can  be used in a choice (see 0) is entirely dependent on whether the original 0 action could be used in an alt. For all of CHP's channels, this is true, but 4 for your own custom receive actions, probably not. }:Given a writing channel end, gives back the corresponding z. ~Like }7, but always applies the given function before sending  the item. :Given a reading channel end, gives back the corresponding y. Like 8, but always applies the given function after receiving  an item. OCreates a custom send operation. The first parameter should perform the send, N the second parameter should poison your communication channel, and the third O parameter should check whether the communication channel is already poisoned. " Generally, you will want to use } instead of this function. UCreates a custom receive operation. The first parameter should perform the receive, N the second parameter should poison your communication channel, and the third O parameter should check whether the communication channel is already poisoned. " Generally, you will want to use  instead of this function. 4Acts like a SendAction, but just discards the data. CActs like a RecvAction, but always gives back the given data item. yz{|}~ zy{|}~ yz{|}~    !"#$%&'()*+,-./0123456789:;<=>>?@ABCCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrs t u v w x y z { | } ~     !-L\ t v  chp-plus-1.2.0Control.Concurrent.CHP.TestControl.Concurrent.CHP.Console!Control.Concurrent.CHP.BehavioursControl.Concurrent.CHP.Connect%Control.Concurrent.CHP.Connect.TwoDimControl.Concurrent.CHP.ComposedControl.Concurrent.CHP.CommonControl.Concurrent.CHP.BuffersControl.Concurrent.CHP.ArrowControl.Concurrent.CHP.ActionsCHPTest CHPTestResult CHPTestFail CHPTestPass QuickCheckCHPqcCHPqcCHP' propCHPInOuttestCHP=*=testCHP' withCheck assertCHPassertCHPEqual assertCHP'assertCHPEqual' testCHPInOut ConsoleChanscStdincStdoutcStderrconsoleProcess CHPBehaviourendWhenonceupTo repeatedly repeatedly_repeatedlyRecurserepeatedlyRecurse_ alongside alongside_offerofferAll ChannelPair ConnectableconnectConnectableExtraConnectableParam connectExtra connectList connectList_|<=>|<=><=>||<=> connectWithpipelineConnectpipelineConnectComplete cycleConnectEightWay FourWayDiag aboveLeft belowRight aboveRight belowLeftFourWayabovebelowleftrightwrappedGridFourwrappedGridFour_wrappedGridEightwrappedGridEight_ComposedrunWithrunrun_enrollR enrollAllRconnectR pipelineRpipelineCompleteRcycleRwrappedGridFourRidextIdtapprefixtailsuccparDeltamapmap'filterstreammerger replicaterepeatconsumeconsumeAlongsidejoinjoinListsplitsortersorter' valueStore valueStore' advanceTime fifoBufferinfiniteBufferaccumulatingInfiniteBufferoverflowingBufferoverwritingBufferProcessPipeline runPipelineProcessPipelineLabelrunPipelineLabelarrowProcessLabelarrLabelarrStrictLabel*>>>**<<<**&&&****** arrowProcess arrStrict RecvAction SendAction sendAction recvActionmakeSendActionmakeSendAction'makeRecvActionmakeRecvAction'makeCustomSendActionmakeCustomRecvActionnullSendActionnullRecvActionQuickCheck-2.3Test.QuickCheck.PropertyTestableQCCHPqcResultchpToQC boolToResult chp-2.1.0.1Control.Concurrent.CHP.BaseliftCHPjpo(Control.Concurrent.CHP.Channels.Creation sameChannelconnectRowCycleconnLRconnectColumnsCycleconnABconnectColumnsCycleDiag shiftLeft shiftRight connABDiagconnectRowCycleDiag connLRDiagControl.Concurrent.CHP.Parallel runParallel runParallel_Control.Concurrent.CHP.Enrollenroll EnrollableControl.Concurrent.CHP.BarriersBarrierbaseGHC.Enum Data.MaybeMaybeseqHead removeHeadaddLast Control.ArrowArrow_pipelineLabelsarrControl.Concurrent.CHP.Altalt