In WebPPL, define a function geometric(p) that returns a sample from the geometric distribution using only flip. The geometric distribution here is defined so that geometric(p) returns 1 with probability p, and otherwise returns 1 + geometric(p) (a recursive call). Compute the marginal distribution of geometric(0.5) using Infer({ method: 'enumerate', maxExecutions: 20 }). End your program with var ANSWER = Infer({ method: 'enumerate', maxExecutions: 20, model: function(){ return geometric(0.5); } });.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var geometric = function(p) {2 return flip(p) ? 1 + geometric(p) : 13}45geometric(0.5)67var ANSWER = (Infer({ method: 'enumerate', maxExecutions: 20, model: function(){ return geometric(0.5); } }));8
1var geometric = function(p) {2 return flip(p) ? 1 : 1 + geometric(p);3};45var ANSWER = Infer({ method: 'enumerate', maxExecutions: 20, model: function(){ return geometric(0.5); } });
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
In WebPPL, model the number of heads in three independent fair coin flips. Define a function binomial (no arguments) that samples three Bernoulli(0.5) values a, b, c and returns a + b + c. Then compute the marginal distribution using Infer({ model: binomial }) and assign it to binomialDist. End your program with var ANSWER = binomialDist;.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var binomial = function() {2 var a = sample(Bernoulli({ p: 0.5 }))3 var b = sample(Bernoulli({ p: 0.5 }))4 var c = sample(Bernoulli({ p: 0.5 }))5 return a + b + c6}78var binomialDist = Infer({ model: binomial })910viz(binomialDist)1112var ANSWER = (binomialDist);13
1var binomial = function() {2 var a = flip(0.5) ? 1 : 0;3 var b = flip(0.5) ? 1 : 0;4 var c = flip(0.5) ? 1 : 0;5 return a + b + c;6};78var binomialDist = Infer({ model: binomial });910var ANSWER = binomialDist;
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
In WebPPL, define a function funnyBinomial (no arguments) that samples three independent Bernoulli(0.5) variables a, b, c, applies factor((a || b) ? 0 : -2) to downweight executions where neither a nor b is true, and returns a + b + c. Compute its marginal distribution with Infer({ model: funnyBinomial }) and assign it to funnyBinomialDist. End your program with var ANSWER = funnyBinomialDist;.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var funnyBinomial = function(){2 var a = sample(Bernoulli({ p: 0.5 }))3 var b = sample(Bernoulli({ p: 0.5 }))4 var c = sample(Bernoulli({ p: 0.5 }))5 factor( (a || b) ? 0 : -2)6 return a + b + c}78var funnyBinomialDist = Infer({ model: funnyBinomial })910viz(funnyBinomialDist)1112var ANSWER = (funnyBinomialDist);13
1var funnyBinomial = function() {2 var a = flip(0.5) ? 1 : 0;3 var b = flip(0.5) ? 1 : 0;4 var c = flip(0.5) ? 1 : 0;5 factor((a || b) ? 0 : -2);6 return a + b + c;7};89var funnyBinomialDist = Infer({ model: funnyBinomial });1011var ANSWER = funnyBinomialDist;
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
Rewrite the following recursive factorial function in continuation-passing style (CPS). In CPS, functions never return; instead they call a continuation k with the value they would have returned.
Here is the original factorial:
1var factorial = function(n) {2 if (n == 0) {3 return 1;4 } else {5 return factorial(n-1) * n;6 }7}
Write a WebPPL function cpsFactorial(k, n) in CPS such that it calls k with n! rather than returning it. Then call cpsFactorial(print, 5) as the final expression. End your program with var ANSWER = cpsFactorial(print, 5);.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var cpsFactorial = function(k, n) {2 if (n == 0) {3 k(1);4 } else {5 cpsFactorial(6 function(x){ k(x * n) },7 n - 1);8 }9}1011cpsFactorial(print, 5)1213var ANSWER = (cpsFactorial(function(x){return x;}, 5));14
1var cpsFactorial = function(k, n) {2 if (n == 0) {3 k(1);4 } else {5 cpsFactorial(function(result) {6 k(result * n);7 }, n - 1);8 }9};1011var ANSWER = cpsFactorial(print, 5);
120.0000
120.0000
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ✓val+ | — | — | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ✓val+ | — | — | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ✓val+ | — | — | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ✓val+ | — | — | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ✓val+ | — | — | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ✓val+ | — | — | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ✓val+ | — | — | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ✓val+ | — | — | · |
Extend a CPS factorial function to handle negative inputs using an error continuation. Write a WebPPL function totalCpsFactorial(k, err, n) in continuation-passing style where:
- If n < 0, call err with an error message string (any string)
- If n == 0, call k with 1
- Otherwise, recurse: call totalCpsFactorial with a continuation that multiplies the result by n, passing along err and n - 1
End your program with this exact binding:
1var ANSWER = totalCpsFactorial(function(x){return x;}, function(e){return 'err';}, -1);
The success continuation is identity; the error continuation returns the constant string 'err' (it ignores its argument). The whole expression's value is 'err' for n = -1.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var totalCpsFactorial = function(k, err, n) {2 if (n < 0) {3 err("cpsFactorial: n < 0!")4 } else if (n == 0) {5 k(1);6 } else {7 totalCpsFactorial(8 function(x){ k(x * n) },9 err,10 n - 1);11 }12}1314var printError = function(x){15 print("Error: " + x);16}1718totalCpsFactorial(print, printError, 5)19totalCpsFactorial(print, printError, -1)2021var ANSWER = (totalCpsFactorial(function(x){return x;}, function(e){return 'err';}, -1));22
1var totalCpsFactorial = function(k, err, n) {2 if (n < 0) {3 return err("factorial undefined for negative numbers");4 } else if (n === 0) {5 return k(1);6 } else {7 return totalCpsFactorial(function(result) {8 return k(n * result);9 }, err, n - 1);10 }11};1213var ANSWER = totalCpsFactorial(function(x){return x;}, function(e){return 'err';}, -1);
"err"
"err"
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ✓val+ | — | — | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ✓val+ | — | — | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ✓val+ | — | — | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ✓val+ | — | — | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ✓val+ | — | — | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ✓val+ | — | — | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ✓val+ | — | — | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ✓val+ | — | — | · |
In WebPPL, define a function binomial (no arguments) that samples three independent Bernoulli random variables with probabilities 0.1, 0.9, and 0.1 respectively (variables a, b, c), and returns a + b + c.
Then compute and return a record with three keys, each the marginal distribution of binomial under a different enumeration strategy (all with maxExecutions: 10):
- depthFirst: Infer({ model: binomial, method: "enumerate", maxExecutions: 10, strategy: "depthFirst" })
- breadthFirst: Infer({ model: binomial, method: "enumerate", maxExecutions: 10, strategy: "breadthFirst" })
- likelyFirst: Infer({ model: binomial, method: "enumerate", maxExecutions: 10, strategy: "likelyFirst" })
End with var ANSWER = { depthFirst: depthFirstDist, breadthFirst: breadthFirstDist, likelyFirst: likelyFirstDist };.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var binomial = function(){2 var a = sample(Bernoulli({ p: 0.1 }))3 var b = sample(Bernoulli({ p: 0.9 }))4 var c = sample(Bernoulli({ p: 0.1 }))5 return a + b + c6}78var maxExec = 10910viz(Infer({11 model: binomial,12 method: 'enumerate',13 maxExecutions: maxExec,14 strategy: 'depthFirst'15}));1617viz(Infer({18 model: binomial,19 method: 'enumerate',20 maxExecutions: maxExec,21 strategy: 'breadthFirst'22}));2324viz(Infer({25 model: binomial,26 method: 'enumerate',27 maxExecutions: maxExec,28 strategy: 'likelyFirst',29}));3031var ANSWER = ({depthFirst: Infer({model: binomial, method: 'enumerate', maxExecutions: 10, strategy: 'depthFirst'}), breadthFirst: Infer({model: binomial, method: 'enumerate', maxExecutions: 10, strategy: 'breadthFirst'}), likelyFirst: Infer({model: binomial, method: 'enumerate', maxExecutions: 10, strategy: 'likelyFirst'})});32
1var binomial = function() {2 var a = sample(Bernoulli({p: 0.1})) ? 1 : 0;3 var b = sample(Bernoulli({p: 0.9})) ? 1 : 0;4 var c = sample(Bernoulli({p: 0.1})) ? 1 : 0;5 return a + b + c;6};78var depthFirstDist = Infer({ model: binomial, method: "enumerate", maxExecutions: 10, strategy: "depthFirst" });9var breadthFirstDist = Infer({ model: binomial, method: "enumerate", maxExecutions: 10, strategy: "breadthFirst" });10var likelyFirstDist = Infer({ model: binomial, method: "enumerate", maxExecutions: 10, strategy: "likelyFirst" });1112var ANSWER = { depthFirst: depthFirstDist, breadthFirst: breadthFirstDist, likelyFirst: likelyFirstDist };
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ✓val+ | — | — | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ✓val+ | — | — | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ✓val+ | — | — | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ✓val+ | — | — | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ✓val+ | — | — | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ✓val+ | — | — | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ✓val+ | — | — | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ✓val+ | — | — | · |
In WebPPL, implement a Hidden Markov Model with binary states and observations, and infer the state sequence given an observation sequence.
Define:
- transition(s): returns flip(0.7) if s is true, flip(0.3) otherwise
- observeState(s): returns flip(0.9) if s is true, flip(0.1) otherwise
- hmm(n): recursive function returning {states: [...], observations: [...]} of length n each.
- Base case n == 1: returns {states: [true], observations: [observeState(true)]}
- Recursive case: let prev = hmm(n - 1); let newState = transition(prev.states[prev.states.length - 1]); let newObs = observeState(newState); return {states: prev.states.concat([newState]), observations: prev.observations.concat([newObs])}
Given the observation sequence [false, false, false], infer the marginal distribution over the state sequence using Infer with default options (exact enumeration) and a hard factor(... ? 0 : -Infinity) constraint on r.observations matching the data.
End your program with this exact binding:
1var ANSWER = Infer({model: function() {2 var r = hmm(3);3 factor(_.isEqual(r.observations, [false, false, false]) ? 0 : -Infinity);4 return r.states;5}});
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
123var ANSWER = (Infer({model: function() { var transition = function(s) { return s ? flip(0.7) : flip(0.3); }; var observeState = function(s) { return s ? flip(0.9) : flip(0.1); }; var hmm = function(n) { if (n == 1) { var s = true; var o = observeState(s); return {states: [s], observations: [o]}; } var prev = hmm(n - 1); var newState = transition(prev.states[prev.states.length - 1]); var newObs = observeState(newState); return {states: prev.states.concat([newState]), observations: prev.observations.concat([newObs])}; }; var r = hmm(3); factor(_.isEqual(r.observations, [false, false, false]) ? 0 : -Infinity); return r.states; }}));4
1var transition = function(s) {2 return s ? flip(0.7) : flip(0.3);3};45var observeState = function(s) {6 return s ? flip(0.9) : flip(0.1);7};89var hmm = function(n) {10 if (n == 1) {11 return {states: [true], observations: [observeState(true)]};12 } else {13 var prev = hmm(n - 1);14 var newState = transition(prev.states[prev.states.length - 1]);15 var newObs = observeState(newState);16 return {states: prev.states.concat([newState]), observations: prev.observations.concat([newObs])};17 }18};1920var ANSWER = Infer({model: function() {21 var r = hmm(3);22 factor(_.isEqual(r.observations, [false, false, false]) ? 0 : -Infinity);23 return r.states;24}});
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
In WebPPL, implement a probabilistic context-free grammar (PCFG) and compute the distribution over the next word after "tall John".
Define pcfgTransition(symbol) using rule tables:
- "start" expands to ["NP","V","NP"] (prob 0.4) or ["NP","V"] (prob 0.6)
- "NP" expands to ["A","NP"] (prob 0.4) or ["N"] (prob 0.6)
Use discrete(rules[symbol].probs) to sample the rule index.
Define preTerminal(symbol) returning true for "N", "V", or "A".
Define terminal(symbol) using word tables:
- "N": "John" (0.6), "soup" (0.4)
- "V": "loves" (0.3), "hates" (0.3), "runs" (0.4)
- "A": "tall" (0.6), "salty" (0.4)
Use discrete(rules[symbol].probs) to sample.
Define mutually recursive pcfg(symbol) and expand(symbols) to generate a terminal yield as an array.
Define a model function that samples y = pcfg("start"), applies factor(_.isEqual(y.slice(0,2), ["tall","John"]) ? 0 : -Infinity), and returns y[2] ? y[2] : "".
End with var ANSWER = Infer({ model, method: "enumerate", maxExecutions: 20 });.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var pcfgTransition = function(symbol) {2 var rules = {'start': {rhs: [['NP', 'V', 'NP'], ['NP', 'V']], probs: [0.4, 0.6]},3 'NP': {rhs: [['A', 'NP'], ['N']], probs: [0.4, 0.6]} }4 return rules[symbol].rhs[ discrete(rules[symbol].probs) ]5}67var preTerminal = function(symbol) {8 return symbol=='N' | symbol=='V' | symbol=='A'9}1011var terminal = function(symbol) {12 var rules = {'N': {words: ['John', 'soup'], probs: [0.6, 0.4]},13 'V': {words: ['loves', 'hates', 'runs'], probs: [0.3, 0.3, 0.4]},14 'A': {words: ['tall', 'salty'], probs: [0.6, 0.4]} }15 return rules[symbol].words[ discrete(rules[symbol].probs) ]16}171819var pcfg = function(symbol) {20 preTerminal(symbol) ? [terminal(symbol)] : expand(pcfgTransition(symbol))21}2223var expand = function(symbols) {24 if(symbols.length==0) {25 return []26 } else {27 var f = pcfg(symbols[0])28 return f.concat(expand(symbols.slice(1)))29 }30}3132var model = function(){33 var y = pcfg("start")34 factor(_.isEqual(y.slice(0,2), ["tall", "John"]) ? 0 : -Infinity) // yield starts with "tall John"35 return y[2] ? y[2] : "" // distribution on next word?36}3738viz.table(Infer({ model, method: 'enumerate', maxExecutions: 20}))3940var ANSWER = (Infer({ model, method: 'enumerate', maxExecutions: 20 }));41
1var rules = {2 "start": {3 expansions: [["NP","V","NP"], ["NP","V"]],4 probs: [0.4, 0.6]5 },6 "NP": {7 expansions: [["A","NP"], ["N"]],8 probs: [0.4, 0.6]9 },10 "N": {11 expansions: [["John"], ["soup"]],12 probs: [0.6, 0.4]13 },14 "V": {15 expansions: [["loves"], ["hates"], ["runs"]],16 probs: [0.3, 0.3, 0.4]17 },18 "A": {19 expansions: [["tall"], ["salty"]],20 probs: [0.6, 0.4]21 }22};2324var pcfgTransition = function(symbol) {25 var idx = discrete(rules[symbol].probs);26 return rules[symbol].expansions[idx];27};2829var preTerminal = function(symbol) {30 return symbol === "N" || symbol === "V" || symbol === "A";31};3233var terminal = function(symbol) {34 var idx = discrete(rules[symbol].probs);35 return rules[symbol].expansions[idx][0];36};3738var pcfg = function(symbol) {39 if (preTerminal(symbol)) {40 return [terminal(symbol)];41 } else {42 var expansion = pcfgTransition(symbol);43 return expand(expansion);44 }45};4647var expand = function(symbols) {48 if (symbols.length === 0) {49 return [];50 } else {51 var first = symbols[0];52 var rest = symbols.slice(1);53 var firstYield = pcfg(first);54 var restYield = expand(rest);55 return firstYield.concat(restYield);56 }57};5859var model = function() {60 var y = pcfg("start");61 factor(_.isEqual(y.slice(0, 2), ["tall", "John"]) ? 0 : -Infinity);62 return y[2] ? y[2] : "";63};6465var ANSWER = Infer({ model: model, method: "enumerate", maxExecutions: 20 });
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
In WebPPL, implement an incrementalized HMM that incorporates observations stepwise during recursion rather than at the end.
Define:
- transition(s): returns flip(0.7) if s, else flip(0.3)
- observeState(s): returns flip(0.9) if s, else flip(0.1)
- trueObs = [false, false, false]
- hmmRecur(n, states, observations): samples newState via transition from states[states.length-1], samples newObs via observeState, immediately applies factor(newObs == trueObs[observations.length] ? 0 : -Infinity), then recurses (n > 1) or returns {states: newStates, observations: newObservations}
- hmm(n): calls hmmRecur(n, [true], [])
Define a model function that runs var r = hmm(3) and returns r.states. Compute Infer({ model }) and assign to ANSWER. End with var ANSWER = Infer({ model });.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1///fold:2var transition = function(s) {3 return s ? flip(0.7) : flip(0.3)4}56var observeState = function(s) {7 return s ? flip(0.9) : flip(0.1)8}910var trueObs = [false, false, false]11///1213var hmmRecur = function(n, states, observations){14 var newState = transition(states[states.length-1])15 var newObs = observeState(newState)16 factor(newObs==trueObs[observations.length] ? 0 : -Infinity)17 var newStates = states.concat([newState])18 var newObservations = observations.concat([newObs])19 return (n==1) ? { states: newStates, observations: newObservations } :20 hmmRecur(n-1, newStates, newObservations)21}2223var hmm = function(n) {24 return hmmRecur(n, [true], [])25}2627var model = function(){28 var r = hmm(3)29 return r.states30}3132viz.table(Infer({ model }))3334var ANSWER = (Infer({ model }));35
1var transition = function(s) {2 return s ? flip(0.7) : flip(0.3);3};45var observeState = function(s) {6 return s ? flip(0.9) : flip(0.1);7};89var trueObs = [false, false, false];1011var hmmRecur = function(n, states, observations) {12 var newState = transition(states[states.length - 1]);13 var newObs = observeState(newState);14 factor(newObs == trueObs[observations.length] ? 0 : -Infinity);15 var newStates = states.concat([newState]);16 var newObservations = observations.concat([newObs]);17 return n > 118 ? hmmRecur(n - 1, newStates, newObservations)19 : { states: newStates, observations: newObservations };20};2122var hmm = function(n) {23 return hmmRecur(n, [true], []);24};2526var model = function() {27 var r = hmm(3);28 return r.states;29};3031var ANSWER = Infer({ model });
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ◉TV<.05 | 0.029 | 0.0051 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
In WebPPL, implement an HMM using sampleWithFactor to simultaneously sample observations and incorporate evidence at each step.
Define:
- transition(s): returns flip(0.7) if s, else flip(0.3)
- observeState: a cached function — cache(function(s) { return Bernoulli({p: s ? .9 : .1}) }) — that returns a distribution object
- trueObs = [false, false, false]
- hmmRecur(n, states, observations): samples newState = transition(last(states)), then samples newObs using sampleWithFactor(observeState(newState), function(v){ return v == trueObs[observations.length] ? 0 : -Infinity }), extends both arrays, recurses or returns {states: ..., observations: ...}
- hmm(n): calls hmmRecur(n, [true], [])
Define a model function returning hmm(3).states. End with var ANSWER = Infer({ model, method: "enumerate", maxExecutions: 500 });.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1///fold:2var transition = function(s) {3 return s ? flip(0.7) : flip(0.3)4}56var observeState = cache(function(s) {7 return Bernoulli({p: s ? .9 : .1})8})910var trueObs = [false, false, false]11///1213var hmmRecur = function(n, states, observations){14 var newState = transition(states[states.length-1])15 var newObs = sampleWithFactor(16 observeState(newState),17 function(v){return v==trueObs[observations.length] ? 0 : -Infinity})18 var newStates = states.concat([newState])19 var newObservations = observations.concat([newObs])20 return ((n==1) ?21 { states: newStates, observations: newObservations } :22 hmmRecur(n-1, newStates, newObservations));23}2425var hmm = function(n) {26 return hmmRecur(n,[true],[])27}2829var model = function(){30 var r = hmm(3)31 return r.states32}3334viz.table(Infer({ model, method: 'enumerate', maxExecutions: 500 }))3536var ANSWER = (Infer({ model, method: 'enumerate', maxExecutions: 500 }));37
1var transition = function(s) {2 return s ? flip(0.7) : flip(0.3);3};45var observeState = cache(function(s) {6 return Bernoulli({p: s ? 0.9 : 0.1});7});89var trueObs = [false, false, false];1011var last = function(arr) {12 return arr[arr.length - 1];13};1415var hmmRecur = function(n, states, observations) {16 var newState = transition(last(states));17 var newObs = sampleWithFactor(observeState(newState), function(v) {18 return v == trueObs[observations.length] ? 0 : -Infinity;19 });20 var newStates = states.concat([newState]);21 var newObservations = observations.concat([newObs]);22 return (newObservations.length === n) ?23 {states: newStates, observations: newObservations} :24 hmmRecur(n, newStates, newObservations);25};2627var hmm = function(n) {28 return hmmRecur(n, [true], []);29};3031var model = function() {32 return hmm(3).states;33};3435var ANSWER = Infer({model: model, method: "enumerate", maxExecutions: 500});
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
In WebPPL, demonstrate the technique of inserting canceling heuristic factors to guide enumeration. Here is the original model:
1var binomial = function(){2 var a = sample(Bernoulli({ p: 0.1 }))3 var b = sample(Bernoulli({ p: 0.9 }))4 var c = sample(Bernoulli({ p: 0.1 }))5 factor((a||b||c) ? 0 : -10)6 return a + b + c7}
Rewrite this as binomialHeuristic by splitting the single end-of-model factor into three interleaved factors that cancel correctly:
- After sampling a: factor(a ? 0 : -1)
- After sampling b: factor(((a||b) ? 0 : -1) - (a ? 0 : -1))
- After sampling c: factor(((a||b||c) ? 0 : -10) - ((a||b) ? 0 : -1))
Run both models with Infer({ model: ..., method: "enumerate", maxExecutions: 2 }). End with var ANSWER = { original: Infer({model: binomial, method: "enumerate", maxExecutions: 2}), heuristic: Infer({model: binomialHeuristic, method: "enumerate", maxExecutions: 2}) };.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var binomial = function(){2 var a = sample(Bernoulli({ p: 0.1 }))3 factor(a ? 0 : -1)4 var b = sample(Bernoulli({ p: 0.9 }))5 factor(((a||b)?0:-1) - (a?0:-1))6 var c = sample(Bernoulli({ p: 0.1 }))7 factor(((a||b||c) ? 0:-10) - ((a||b)?0:-1))8 return a + b + c9}1011viz(Infer({ model: binomial, method: 'enumerate', maxExecutions: 2 }))1213var ANSWER = ({ original: Infer({model: function(){ var a = sample(Bernoulli({ p: 0.1 })); var b = sample(Bernoulli({ p: 0.9 })); var c = sample(Bernoulli({ p: 0.1 })); factor((a||b||c) ? 0 : -10); return a + b + c }, method: 'enumerate', maxExecutions: 2}), heuristic: Infer({model: binomial, method: 'enumerate', maxExecutions: 2}) });14
1var binomial = function(){2 var a = sample(Bernoulli({ p: 0.1 }))3 var b = sample(Bernoulli({ p: 0.9 }))4 var c = sample(Bernoulli({ p: 0.1 }))5 factor((a||b||c) ? 0 : -10)6 return a + b + c7}89var binomialHeuristic = function(){10 var a = sample(Bernoulli({ p: 0.1 }))11 factor(a ? 0 : -1)12 var b = sample(Bernoulli({ p: 0.9 }))13 factor(((a||b) ? 0 : -1) - (a ? 0 : -1))14 var c = sample(Bernoulli({ p: 0.1 }))15 factor(((a||b||c) ? 0 : -10) - ((a||b) ? 0 : -1))16 return a + b + c17}1819var ANSWER = {20 original: Infer({ model: binomial, method: "enumerate", maxExecutions: 2 }),21 heuristic: Infer({ model: binomialHeuristic, method: "enumerate", maxExecutions: 2 })22};
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ✓val+ | — | — | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ✓val+ | — | — | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ✓val+ | — | — | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ✗val- | — | — | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ✓val+ | — | — | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ✓val+ | — | — | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ✓val+ | — | — | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ✓val+ | — | — | · |
In WebPPL, implement a simple HMM with binary states and soft observation factors.
Define hmm(states, observations) recursively:
- prevState is the last element of states
- Sample state from Bernoulli({p: prevState ? .9 : .1})
- Apply factor((state == observations[0]) ? 0 : -2) to soft-match the state to the first observation
- If observations is empty, return states; otherwise recurse with states.concat([state]) and observations.slice(1)
Set var observations = [true, true, true, true] and var startState = false. Compute the posterior and assign to ANSWER. End with var ANSWER = Infer({ model() { return hmm([startState], observations) } });.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var hmm = function(states, observations){2 var prevState = states[states.length - 1];3 var state = sample(Bernoulli({p: prevState ? .9 : .1}));4 factor((state == observations[0]) ? 0 : -2);5 if (observations.length == 0) {6 return states;7 } else {8 return hmm(states.concat([state]), observations.slice(1));9 }10}1112var observations = [true, true, true, true];13var startState = false;1415viz.table(Infer({16 model() {17 return hmm([startState], observations)18 }19}))2021var ANSWER = (Infer({ model() { return hmm([startState], observations) } }));22
1var observations = [true, true, true, true];2var startState = false;34var hmm = function(states, observations) {5 if (observations.length === 0) {6 return states;7 }8 var prevState = states[states.length - 1];9 var state = sample(Bernoulli({p: prevState ? 0.9 : 0.1}));10 factor((state == observations[0]) ? 0 : -2);11 return hmm(states.concat([state]), observations.slice(1));12};1314var ANSWER = Infer({ model: function() { return hmm([startState], observations); } });
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ◉TV<.05 | 0.048 | 0.0650 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ◉TV<.05 | 1.1e-16 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ◉TV<.05 | 1.1e-16 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ◉TV<.05 | 1.1e-16 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ◉TV<.05 | 1.1e-16 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ◉TV<.05 | 1.1e-16 | 0.0000 | · |
In WebPPL, implement a one-dimensional Gaussian random walk and compute the distribution over whether the walk ends above its starting region.
Define:
- last(xs): returns xs[xs.length - 1]
- init(dim): returns an array of dim samples from gaussian(200, 1) using repeat
- transition(pos): maps over pos, replacing each coordinate x with a sample from gaussian(x, 10)
- gaussianRandomWalk(n, dim): recursively builds a list of positions; base case (n==1) is [init(dim)]; recursive case appends transition(last(prevStates)) to the previous state list
Compute the marginal distribution over whether the final x-coordinate of a 5-step 1D walk exceeds 200. Use Infer with method 'forward' and 1000 samples. End with var ANSWER = Infer({ method: 'forward', samples: 1000, model: function(){ return last(gaussianRandomWalk(5, 1))[0] > 200; } });.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1///fold:2var drawLines = function(canvas, start, positions){3 if (positions.length == 0) { return []; }4 var next = positions[0];5 canvas.line(start[0], start[1], next[0], next[1], 4, 0.2);6 drawLines(canvas, next, positions.slice(1));7 return;8}910var last = function(xs){11 return xs[xs.length - 1];12}13///1415var init = function(dim){16 return repeat(dim, function(){ return gaussian(200, 1) });17}1819var transition = function(pos){20 return map(21 function(x){ return gaussian(x, 10); },22 pos23 );24};2526var gaussianRandomWalk = function(n, dim) {27 var prevStates = (n==1) ? [init(dim)] : gaussianRandomWalk(n-1, dim);28 var newState = transition(last(prevStates));29 return prevStates.concat([newState]);30};3132var positions = gaussianRandomWalk(100, 2);333435// Draw model output3637var canvas = Draw(400, 400, true)38drawLines(canvas, positions[0], positions.slice(1))3940var ANSWER = (Infer({ method: 'forward', samples: 1000, model: function(){ return last(gaussianRandomWalk(5, 1))[0] > 200; } }));41
1var last = function(xs) { return xs[xs.length - 1]; };23var init = function(dim) { return repeat(dim, function() { return gaussian(200, 1); }); };45var transition = function(pos) { return map(function(x) { return gaussian(x, 10); }, pos); };67var gaussianRandomWalk = function(n, dim) {8 if (n == 1) {9 return [init(dim)];10 } else {11 var prevStates = gaussianRandomWalk(n - 1, dim);12 return prevStates.concat([transition(last(prevStates))]);13 }14};1516var ANSWER = Infer({ method: 'forward', samples: 1000, model: function(){ return last(gaussianRandomWalk(5, 1))[0] > 200; } });
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ◉TV<.05 | 0.001 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ◉TV<.05 | 0.001 | 0.0000 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ◉TV<.05 | 0.001 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ◉TV<.05 | 0.001 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ◉TV<.05 | 0.001 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ◉TV<.05 | 0.001 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ◉TV<.05 | 0.001 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ◉TV<.05 | 0.001 | 0.0000 | · |
In WebPPL, implement a one-dimensional semi-Markov random walk with momentum and compute the distribution over whether the walk ends above its starting region.
Define:
- last(xs): returns xs[xs.length - 1]
- secondLast(xs): returns xs[xs.length - 2]
- init(dim): returns an array of dim samples from gaussian(200, 1) using repeat
- transition(lastPos, secondLastPos): uses map2 over both arrays; each new coordinate is sampled from gaussian(lastX + (lastX - secondLastX) * 0.7, 3) where lastX and secondLastX are the corresponding coordinates
- semiMarkovWalk(n, dim): base case (n==2) returns [init(dim), init(dim)]; recursive case appends transition(last(prevStates), secondLast(prevStates))
Compute the marginal distribution over whether the final x-coordinate of a 6-step 1D walk exceeds 200. Use Infer with method 'forward' and 1000 samples. End with var ANSWER = Infer({ method: 'forward', samples: 1000, model: function(){ return last(semiMarkovWalk(6, 1))[0] > 200; } });.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1///fold:2var drawLines = function(canvas, start, positions){3 if (positions.length == 0) { return []; }4 var next = positions[0];5 canvas.line(start[0], start[1], next[0], next[1], 4, 0.2);6 drawLines(canvas, next, positions.slice(1));7 return;8}9///1011var init = function(dim){12 return repeat(dim, function(){ return gaussian(200, 1) });13}1415var transition = function(lastPos, secondLastPos){16 return map2(17 function(lastX, secondLastX){18 var momentum = (lastX - secondLastX) * .7;19 return gaussian(lastX + momentum, 3);20 },21 lastPos,22 secondLastPos23 );24};2526var semiMarkovWalk = function(n, dim) {27 var prevStates = (n==2) ? [init(dim), init(dim)] : semiMarkovWalk(n-1, dim);28 var newState = transition(last(prevStates), secondLast(prevStates));29 return prevStates.concat([newState]);30};3132var positions = semiMarkovWalk(80, 2);333435// Draw model output3637var canvas = Draw(400, 400, true)38drawLines(canvas, positions[0], positions.slice(1))3940var ANSWER = (Infer({ method: 'forward', samples: 1000, model: function(){ return last(semiMarkovWalk(6, 1))[0] > 200; } }));41
1var last = function(xs) { return xs[xs.length - 1]; };2var secondLast = function(xs) { return xs[xs.length - 2]; };3var init = function(dim) { return repeat(dim, function() { return gaussian(200, 1); }); };4var transition = function(lastPos, secondLastPos) {5 return map2(function(lastX, secondLastX) {6 return gaussian(lastX + (lastX - secondLastX) * 0.7, 3);7 }, lastPos, secondLastPos);8};9var semiMarkovWalk = function(n, dim) {10 if (n == 2) {11 return [init(dim), init(dim)];12 } else {13 var prevStates = semiMarkovWalk(n - 1, dim);14 return prevStates.concat([transition(last(prevStates), secondLast(prevStates))]);15 }16};1718var ANSWER = Infer({ method: 'forward', samples: 1000, model: function(){ return last(semiMarkovWalk(6, 1))[0] > 200; } });
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ◉TV<.05 | 0.018 | 0.0006 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ◉TV<.05 | 0.018 | 0.0006 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ◉TV<.05 | 0.018 | 0.0006 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ◉TV<.05 | 0.018 | 0.0006 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ◉TV<.05 | 0.018 | 0.0006 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ◉TV<.05 | 0.018 | 0.0006 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ◉TV<.05 | 0.018 | 0.0006 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ◉TV<.05 | 0.018 | 0.0006 | · |
In WebPPL, implement a two-component Gaussian mixture model with a component-selection function, and compute the exact distribution over which component a draw comes from.
Define:
- var mixtureWeight = 0.4 (fixed)
- var mean1 = 100, var std1 = 10
- var mean2 = 200, var std2 = 15
- gaussianMixture(): returns a sample from gaussian(mean1, std1) if flip(mixtureWeight), else from gaussian(mean2, std2)
- gaussianMixtureComponent(): returns 1 if flip(mixtureWeight), else 2
End your program with this exact binding:
1var ANSWER = Infer({model: function() { return flip(0.4) ? 1 : 2; }});
The ANSWER expression inlines the component selection so it doesn't depend on your function names; the distribution is over {1, 2} with probabilities {0.4, 0.6}.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
123var ANSWER = (Infer({model: function() { return flip(0.4) ? 1 : 2; }}));4
1var mixtureWeight = 0.4;2var mean1 = 100;3var std1 = 10;4var mean2 = 200;5var std2 = 15;67var gaussianMixture = function() {8 return flip(mixtureWeight) ? gaussian(mean1, std1) : gaussian(mean2, std2);9};1011var gaussianMixtureComponent = function() {12 return flip(mixtureWeight) ? 1 : 2;13};1415var ANSWER = Infer({model: function() { return flip(0.4) ? 1 : 2; }});
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
In WebPPL, define a function skewBinomial (no arguments) that samples three independent fair coin flips a, b, c from Bernoulli({p: 0.5}), applies factor((a|b) ? 0 : -1) to downweight executions where neither a nor b is true, and returns a + b + c. Compute the exact marginal distribution using enumeration. End with var ANSWER = Infer({ model: skewBinomial });.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var skewBinomial = function(){2 var a = sample(Bernoulli({p: 0.5}))3 var b = sample(Bernoulli({p: 0.5}))4 var c = sample(Bernoulli({p: 0.5}))5 factor( (a|b)?0:-1 )6 return a + b + c7}89viz(Infer({ model: skewBinomial }))1011var ANSWER = (Infer({ model: skewBinomial }));12
1var skewBinomial = function() {2 var a = sample(Bernoulli({p: 0.5}));3 var b = sample(Bernoulli({p: 0.5}));4 var c = sample(Bernoulli({p: 0.5}));5 factor((a | b) ? 0 : -1);6 return a + b + c;7};89var ANSWER = Infer({ model: skewBinomial });
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
In WebPPL, define a function skewBinomial (no arguments) that samples three independent fair coin flips a, b, c from Bernoulli({p: 0.5}), applies factor((a|b) ? 0 : -1) to downweight executions where neither a nor b is true, and returns a + b + c. Approximate the marginal distribution using MCMC with 1000 samples and 200 burn-in steps. End with var ANSWER = Infer({ model: skewBinomial, method: "MCMC", samples: 1000, burn: 200 });.
system prompt
(system prompt loads here)
WebPPL primer
(primer loads here)
1var skewBinomial = function(){2 var a = sample(Bernoulli({p: 0.5}))3 var b = sample(Bernoulli({p: 0.5}))4 var c = sample(Bernoulli({p: 0.5}))5 factor( (a|b)?0:-1 )6 return a + b + c7}89viz(Infer({ model: skewBinomial }))1011var ANSWER = (Infer({ model: skewBinomial, method: 'MCMC', samples: 1000, burn: 200 }));12
1var skewBinomial = function() {2 var a = sample(Bernoulli({p: 0.5}));3 var b = sample(Bernoulli({p: 0.5}));4 var c = sample(Bernoulli({p: 0.5}));5 factor((a | b) ? 0 : -1);6 return a + b + c;7};89var ANSWER = Infer({ model: skewBinomial, method: "MCMC", samples: 1000, burn: 200 });
| run | flags | bucket | TV | KL | actions |
|---|---|---|---|---|---|
| haiku-45-noprimer-dippl | haiku-4.5 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-primer-dippl | haiku-4.5 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-noprimer-dippl | haiku-4.5 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| haiku-45-think-primer-dippl | haiku-4.5 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-noprimer-dippl | sonnet-4.6 no-primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-primer-dippl primary | sonnet-4.6 +primer | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-noprimer-dippl | sonnet-4.6 no-primer thinking | ●TV=0 | 0.000 | 0.0000 | · |
| sonnet-46-think-primer-dippl | sonnet-4.6 +primer thinking | ●TV=0 | 0.000 | 0.0000 | · |