Skip to content

Instantly share code, notes, and snippets.

@carld
Last active February 27, 2017 10:44
Show Gist options
  • Save carld/ab42b642af9a886572ef574f3668e483 to your computer and use it in GitHub Desktop.
Save carld/ab42b642af9a886572ef574f3668e483 to your computer and use it in GitHub Desktop.
PAIP, Chapter 5.3, in Javascript
var variablep = function(x) {
// String is a primitive, so x instanceof String does not do what you think
return (typeof x === "string") && (x[0] == "?");
}
var equal = function(x,y) {
if (x === y) return true;
if (x == y) return true;
if (typeof x === 'string' && typeof y === 'string'
&& x.toLowerCase() == y.toLowerCase()) return true;
if (typeof x === 'array' && typeof y === 'array' && x.length == y.length) {
for (var i = 0; i < x.length; i++) {
if (equal(x[i], y[i]) == false) { return false; }
}
return true;
}
return false;
}
var matchvariable = function(var_, input, bindings) {
bindings = JSON.parse(JSON.stringify(bindings)); //copy this object that's been passed by reference
var binding = bindings[var_];
if (!binding) {
bindings[var_] = input;
return bindings;
}
if (equal(input,binding)) { return bindings; }
return null;
}
var consp = function(x) {
return (x instanceof Array) && x.length != 0;
}
var patmatch = function(pattern, input, bindings) {
if (bindings === undefined) { bindings = {}; }
if (bindings == null) { return null; }
if (variablep(pattern)) { return matchvariable(pattern, input, bindings); }
if (equal(pattern,input)) { return bindings; }
if (segmentpatternp(pattern)) { return segmentmatch(pattern, input, bindings); }
if (consp(pattern) && consp(input)) {
return patmatch(pattern.slice(1), input.slice(1),
patmatch(pattern[0], input[0], bindings));
}
return null;
}
var segmentpatternp = function(pattern) {
return (consp(pattern) && (pattern[0][0] == "?*"));
}
var segmentmatch = function(pattern, input, bindings, start) {
if (start === undefined) { start = 0; }
var var_ = pattern[0][1];
var pat = pattern.slice(1);
if (pat.length == 0) {
return matchvariable(var_, input, bindings);
} else {
// assume that pat starts with a constant
var pos = input.indexOf(pat[0], start);
if (pos == -1) {
return null;
} else {
var b2 = patmatch(pat, input.slice(pos),
matchvariable(var_, input.slice(0, pos), bindings));
// if this match failed try a longer one
if (b2 == null) {
return segmentmatch(pattern, input, bindings, pos + 1);
} else {
return b2;
}
}
}
}
var rulepattern = function(rule) {
return rule[0];
}
var ruleresponses = function(rule) {
return rule.slice(1);
}
var parser = function(text) {
return text.split(/\s+/g);
}
//patmatch([["?*","?p"],"need",["?*","?x"]],["mr","hulot","and","i","need","a","vacation"]);
//patmatch([['?*','?x'],'is','a',['?*','?y']],['what','he','is','is','a','fool']);
//patmatch([['?*','?x'],'a','b',['?*','?x']],['1','2','a','b','a','b','1','2','a','b']);
var switchviewpoint = function(words) {
return words.map(function(w) {
var ll = [[/I/g,'you'],[/you/g,'I'],[/me/g,'you'],
[/am/g,'are'],[/my/g,'your']];
for (let val of ll) {
w = w.replace(val[0], val[1]);
}
return w;
});
}
function getRandomIntInclusive(min, max) { /* from MDN */
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var randomelt = function(x) {
var r = getRandomIntInclusive(0,x.length-1);
return x[r];
}
var userules = function(input) {
input = input.split(/\s+/g);
input = switchviewpoint(input);
r = elizarules.find(function(rule) {
return patmatch(rulepattern(rule), input);
});
if (r) {
bindings = patmatch(rulepattern(r), input);
resp = randomelt(ruleresponses(r));
words = resp;
words = words.map(function(w) {
if (bindings[w]) {
return bindings[w].join(' ');
}
return w;
}).join(' ');
return words;
}
return "Weizenbaum Meditation";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment