Last active
February 27, 2017 10:44
-
-
Save carld/ab42b642af9a886572ef574f3668e483 to your computer and use it in GitHub Desktop.
PAIP, Chapter 5.3, in Javascript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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