/<path-to-webppl>/src/header.js:339
throw "Enumerate can only be used with ERPs that have support function.";
^
Enumerate can only be used with ERPs that have support function.
var neg = function(Q){ return function(x){return !Q(x)} }
// original verion
var makeObj1 = function(name) {
return {name: name,
blond: flip(0.5),
nice: flip(0.5)}
}
// augmented with position flags
var makeObj2 = function(name) {
return {name: name,
pos: [flip(0.5), flip(0.5)],
blond: flip(0.5),
nice: flip(0.5)}
}
// augmented with position coordinates
var makeObj3 = function(name) {
return {name: name,
pos: [uniform(0.5), uniform(0.5)],
blond: flip(0.5),
nice: flip(0.5)}
}
var makeObj = makeObj3
var lexical_meaning = function(word, world) {
var wordMeanings = {
"blond" : {
sem: function(obj){return obj.blond},
syn: {dir:'L', int:'NP', out:'S'} },
"nice" : {
sem: function(obj){return obj.nice},
syn: {dir:'L', int:'NP', out:'S'} },
"Bob" : {
sem: find(world, function(obj){return obj.name=="Bob"}),
syn: 'NP' },
"some" : {
sem: function(P){
return function(Q){return filter(filter(world, P), Q).length>0}},
syn: {dir:'R',
int:{dir:'L', int:'NP', out:'S'},
out:{dir:'R',
int:{dir:'L', int:'NP', out:'S'},
out:'S'}} },
"all" : {
sem: function(P){
return function(Q){return filter(filter(world, P), neg(Q)).length==0}},
syn: {dir:'R',
int:{dir:'L', int:'NP', out:'S'},
out:{dir:'R',
int:{dir:'L', int:'NP', out:'S'},
out:'S'}} }
}
var meaning = wordMeanings[word];
return meaning == undefined?{sem: undefined, syn: ''}:meaning;
}
// The syntaxMatch function is a simple recursion to
// check if two syntactic types are equal.
var syntaxMatch = function(s,t) {
return !s.hasOwnProperty('dir') ? s==t :
s.dir==t.dir & syntaxMatch(s.int,t.int) & syntaxMatch(s.out,t.out)
}
//make a list of the indexes that can (syntactically) apply.
var canApply = function(meanings,i) {
if(i==meanings.length){
return []
}
var s = meanings[i].syn
if (s.hasOwnProperty('dir')){ //a functor
var a = ((s.dir == 'L')?syntaxMatch(s.int, meanings[i-1].syn):false) |
((s.dir == 'R')?syntaxMatch(s.int, meanings[i+1].syn):false)
if(a){return [i].concat(canApply(meanings,i+1))}
}
return canApply(meanings,i+1)
}
var combine_meaning = function(meanings) {
var possibleComb = canApply(meanings,0)
display(possibleComb)
var i = possibleComb[randomInteger(possibleComb.length)]
var s = meanings[i].syn
if (s.dir == 'L') {
var f = meanings[i].sem
var a = meanings[i-1].sem
var newmeaning = {sem: f(a), syn: s.out}
return meanings.slice(0,i-1).concat([newmeaning]).concat(meanings.slice(i+1))
}
if (s.dir == 'R') {
var f = meanings[i].sem
var a = meanings[i+1].sem
var newmeaning = {sem: f(a), syn: s.out}
return meanings.slice(0,i).concat([newmeaning]).concat(meanings.slice(i+2))
}
}
var combine_meanings = function(meanings){
return meanings.length==1 ? meanings[0].sem : combine_meanings(combine_meaning(meanings))
}
var worldPrior = function(objs) {
return [makeObj("Bob"), makeObj("Bill"), makeObj("Alice")]
}
var meaning = function(utterance, world) {
return combine_meanings(
filter(map(utterance.split(" "),
function(w){return lexical_meaning(w, world)}),
function(m){return !(m.sem==undefined)}))
}
var literalListener = function(utterance) {
Enumerate(function(){
var world = worldPrior()
var m = meaning(utterance, world)
factor(m?0:-Infinity)
return world
}, 100)
}
literalListener("all blond people are nice")