forked from probmods/webppl
-
Notifications
You must be signed in to change notification settings - Fork 1
/
pcfg.wppl
42 lines (36 loc) · 1.22 KB
/
pcfg.wppl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
var pcfgTransition = function(symbol) {
var rules = {
'start': {rhs: [['NP', 'V', 'NP'], ['NP', 'V']], probs: [0.4, 0.6]},
'NP': {rhs: [['A', 'NP'], ['N']], probs: [0.4, 0.6]}
};
return rules[symbol].rhs[discrete(rules[symbol].probs)]
}
var preTerminal = function(symbol) {
return symbol == 'N' || symbol == 'V' || symbol == 'A'
}
var terminal = function(symbol) {
var rules = {
'N': {words: ['John', 'soup'], probs: [0.6, 0.4]},
'V': {words: ['loves', 'hates', 'runs'], probs: [0.3, 0.3, 0.4]},
'A': {words: ['tall', 'salty'], probs: [0.6, 0.4]} }
return rules[symbol].words[discrete(rules[symbol].probs)]
}
var pcfg = function(symbol) {
preTerminal(symbol) ? [terminal(symbol)] : expand(pcfgTransition(symbol))
}
var expand = function(symbols) {
if (symbols.length == 0) {
return []
} else {
var f = pcfg(symbols[0])
return f.concat(expand(symbols.slice(1)))
}
}
var arrayEq = function(a, b) {
return (a.length == 0) ? true : (a[0] == b[0] && arrayEq(a.slice(1), b.slice(1)))
}
Enumerate(function() {
var y = pcfg('start')
factor(arrayEq(y.slice(0, 2), ['tall', 'John']) ? 0 : -Infinity) //yield starts with "tall John"
return y[2] ? y[2] : '' //distribution on next word?
}, 300)