`    1:- module(ccp_effects, [ ccstore/2, ccstored/1, cctabled/2, uniform/2, dist/2, dist/3, (:=)/2, sample/2, factor/1 ]).`

# Computational effects for supporting probabilistic models */

```    5:- use_module(library(listutils),   [zip/3]).    6:- use_module(library(delimcc),     [p_shift/2]).    7
8:- meta_predicate :=(3,-), ccstore(:,0), ccstored(:), cctabled(:,0), sample(3,-).```
dist(+Dist:list(pair(prob,A)), -X:A) is nondet
dist(+Ps:list(prob), +Xs:list(A), -X:A) is nondet
Probabilistic choice from given distribtion, which can be supplied as a list of pairs (dist/2) or two lists (dist/3).
```   14dist(Dist,X)  :- zip(Ps,Xs,Dist), p_shift(prob,dist(Ps,Xs,X)).
15dist(Ps,Xs,X) :- p_shift(prob,dist(Ps,Xs,X)).```
uniform(+Xs:list(A), -A) is nondet
Probabilistic choice from uniform distribution over list of values.
`   19uniform(Xs,X) :- p_shift(prob,uniform(Xs,X)).`
sample(+P:pred(-A,+rndstate,-rndstate), -A) is det
Do arbitrary random sampling using capabilities of pack plrand. NB. only works during sampling execution, not explanation search.
`   24sample(P,X)   :- p_shift(prob,sample(P,X)).`
+SW:switch(A) := -X:A is nondet
Probabilistic choice from switch. A switch SW is a callable term of type:
`switch(A) == pred(-switch(A), -X1:list(A), X2:list(A))`

such that `call(SW,ID,X1,X2)` unifies ID with a canonical callable form of the switch and X1-X2 with a difference list of the switch's possible value.

```   33SW := X       :- p_shift(prob,sw(SW,X)).
34
35% arbitrary factor
36factor(F) :- p_shift(prob, factor(F)).```
Execute Work using tabled execution and storing the result under Head. See `ccprism/macros.pl` for an automatic program transformation to manage tabled predicates.
`   42cctabled(Head,Work) :- p_shift(tab, tcall(Head,Work,Inj)), call(Inj).`
Stores a pre-computed 'pseudo-goal' in the tables, similar to Prolog's assert. The result of calling `once(Work)` is stored under the variant form Head. Thus, Work is expected to bind the variables in Head which represent the result of the tabled computation. Stored results should be retrieved using ccstored/1, not cctabled/2.
`   50ccstore(Head,Work)  :- copy_term(Head-Work,H-W), p_shift(tab, tcall(H,once(W),_)).`
`   55ccstored(Head)      :- p_shift(tab, tcall(Head,throw(not_stored(Head)),_))`