|
(function(){ |
|
var fuzzylogic, temps, very, somewhat, propositions, truthiness, answer, domain, slice$ = [].slice; |
|
fuzzylogic = require('fuzzylogic/lib/fuzzylogic'); |
|
temps = { |
|
"freezing": ['reverseGrade', 0, 5], |
|
"cold": ["triangle", 0, 15], |
|
"cool": ["triangle", 10, 20], |
|
"roomTemp": ["triangle", 16, 26], |
|
"warm": ["triangle", 21, 32], |
|
"hot": ["grade", 27, 32] |
|
}; |
|
temps.is = function(temp, description, verbose){ |
|
var ref$, fuzfcn, args, fcn; |
|
ref$ = this[description], fuzfcn = ref$[0], args = slice$.call(ref$, 1); |
|
fcn = fuzzylogic[fuzfcn] || fuzzylogic.triangle; |
|
args.unshift(temp); |
|
if (args.length === 3 && fcn && fcn.length === 4) { |
|
args = [temp, args[1], (args[1] + args[2]) / 2, args[2]]; |
|
} |
|
if (verbose) { |
|
return [fcn.apply(fuzzylogic, args), fuzfcn, args, fcn === fuzzylogic.triangle]; |
|
} else { |
|
return fcn.apply(fuzzylogic, args); |
|
} |
|
}; |
|
temps.toF = function(c){ |
|
return c * 9 / 5 + 32; |
|
}; |
|
temps.toC = function(f){ |
|
return (f - 32) * 5 / 9; |
|
}; |
|
temps.ofList = function(d){ |
|
var temp; |
|
return [["Fahrenheit", this.toF(d)]].concat((function(){ |
|
var results$ = []; |
|
for (temp in this) { |
|
if (typeof this[temp] !== "function") { |
|
results$.push([temp, this.is(d, temp)]); |
|
} |
|
} |
|
return results$; |
|
}.call(this))); |
|
}; |
|
temps.of = function(d){ |
|
var res, temp, own$ = {}.hasOwnProperty; |
|
res = {}; |
|
for (temp in this) if (own$.call(this, temp)) { |
|
if (typeof this[temp] !== "function") { |
|
res[temp] = this.is(d, temp); |
|
} |
|
} |
|
return res; |
|
}; |
|
very = function(x){ |
|
return x * x; |
|
}; |
|
somewhat = function(x){ |
|
return Math.pow(x, 0.5); |
|
}; |
|
propositions = { |
|
very: very, |
|
somewhat: somewhat |
|
}; |
|
truthiness = function(prop){ |
|
switch (false) { |
|
case !(prop >= 1): |
|
return "definitely"; |
|
case !(prop <= 0): |
|
return "definitely not"; |
|
case !(prop >= 0.75): |
|
return "yes"; |
|
case !(prop <= 0.25): |
|
return "no"; |
|
case !(prop >= 0.67): |
|
return "probably"; |
|
case !(prop <= 0.33): |
|
return "probably not"; |
|
default: |
|
return "maybe"; |
|
} |
|
}; |
|
temps.ask = function(msg){ |
|
return msg.match(/\s*(\w+)\s+(-?\d+\.?\d*)(\s+degrees\s*)?\s*(F\s*|C\s+|celsius\s+)?(somewhat|very)?\s*(\w+)?/i); |
|
}; |
|
answer = function(msg, dom){ |
|
var wtype, ref$, message, q, deg, degrees, ForC, prep, weather, prob, mod; |
|
dom == null && (dom = temps); |
|
wtype = []; |
|
try { |
|
ref$ = dom.ask(msg), message = ref$[0], q = ref$[1], deg = ref$[2], degrees = ref$[3], ForC = ref$[4], prep = ref$[5], weather = ref$[6]; |
|
} catch (e$) {} |
|
if (weather != null) { |
|
wtype = [weather]; |
|
} |
|
if (dom.toC && ForC && ForC.charAt(0).toUpperCase() === "F") { |
|
deg = dom.toC(deg); |
|
} |
|
prob = typeof dom[q] === 'function' ? dom[q](deg, weather) : void 8; |
|
if (prob != null && prob.shift) { |
|
wtype = prob; |
|
prob = wtype.shift(); |
|
} |
|
mod = propositions[prep]; |
|
if (typeof mod === "function") { |
|
prob = mod(prob); |
|
} |
|
return [prob, truthiness(prob)].concat(wtype); |
|
}; |
|
temps.highest = function(choices){ |
|
var max, weatherType, temp, deg, own$ = {}.hasOwnProperty; |
|
max = -Infinity; |
|
weatherType = null; |
|
for (temp in choices) if (own$.call(choices, temp)) { |
|
deg = choices[temp]; |
|
if (deg > max) { |
|
max = deg; |
|
weatherType = temp; |
|
} |
|
} |
|
return [max, weatherType]; |
|
}; |
|
temps.find = function(deg, weather){ |
|
var choices; |
|
choices = this.of(deg); |
|
return choices[weather] || this.highest(choices); |
|
}; |
|
domain = function(low, hi, desc, width){ |
|
var range, res$, here, chunks, dom, i, i$, len$, d; |
|
range = hi - low; |
|
width = width || range / (desc.length - 1); |
|
res$ = []; |
|
for (here = low; width < 0 ? here >= hi : here <= hi; here += width) { |
|
res$.push(['triangle', here - width, here, here + width]); |
|
} |
|
chunks = res$; |
|
chunks[0] = ['reverseGrade', low, low + width]; |
|
chunks[chunks.length - 1] = ['grade', hi - width, hi]; |
|
dom = Object.create(temps) || {}; |
|
i = 0; |
|
for (i$ = 0, len$ = desc.length; i$ < len$; ++i$) { |
|
d = desc[i$]; |
|
dom[d] = chunks[i++]; |
|
} |
|
return dom; |
|
}; |
|
/** |
|
|
|
livescript> answer "is 31 degrees hot?" |
|
[ 0.7999999999999998, |
|
'yes', |
|
'hot' ] |
|
|
|
livescript> answer "is 32 degrees hot?" |
|
[ 1, 'definitely', 'hot' ] |
|
|
|
livescript> answer "is 31 F hot?" |
|
[ 0, 'definitely not', 'hot' ] |
|
|
|
livescript> answer "is 31 F cold?" |
|
[ 0, 'definitely not', 'cold' ] |
|
|
|
livescript> answer "find 31 F ?" |
|
[ 1, 'definitely', 'freezing' ] |
|
|
|
livescript> answer "find 32?" |
|
[ 1, 'definitely', 'hot' ] |
|
|
|
livescript> d = domain(0,42,["freezing","cold","cool","roomTemp","warm","hot","blazing"]) |
|
{ freezing: [ 'reverseGrade', 0, 7 ], |
|
cold: [ 'triangle', 0, 7, 14 ], |
|
cool: [ 'triangle', 7, 14, 21 ], |
|
roomTemp: [ 'triangle', 14, 21, 28 ], |
|
warm: [ 'triangle', 21, 28, 35 ], |
|
hot: [ 'triangle', 28, 35, 42 ], |
|
blazing: [ 'grade', 35, 42 ] } |
|
|
|
livescript> d.is(40, "blazing") |
|
0.7142857142857144 |
|
|
|
livescript> answer "is 40 blazing", d |
|
[ 0.7142857142857144, |
|
'probably', |
|
'blazing' ] |
|
|
|
*/ |
|
if (typeof module != 'undefined' && module !== null) { |
|
module.exports = answer; |
|
} |
|
answer.is = temps.is.bind(temps); |
|
answer.find = temps.find.bind(temps); |
|
answer.temperatures = temps; |
|
answer.domain = domain; |
|
}).call(this); |