/ Learner.js
Learner.js
1 (function(global) {//main wrapper 2 /*Here we define all of the functions that may be used throught the porgect that we don't want to be internal*/ 3 4 var hideFunc="function() { /*Look at the scource code if you really want to see how this works! :p*/ }"; 5 function ret(val) { 6 var f=function() { 7 return val; 8 }; 9 Object.defineProperty(f, 'toString', { get: function() { return ret(hideFunc); } });//prevents stackoverflow error by running ret() only when requested 10 Object.defineProperty(f, 'toLocaleString', { get: function() { return ret(hideFunc); } }); 11 return f; 12 } 13 function hide(f) { 14 f.toString=ret(hideFunc); 15 f.toLocaleString=ret(hideFunc); 16 } 17 function applyDefaults(input,defaults) { 18 if ((typeof(defaults)).toString()==='undefined'||(typeof(defaults)).toString()==='string') { 19 return input; 20 }else if ((typeof(input)).toString()==='undefined') { 21 return defaults; 22 }/*else if ((typeof(input)).toString()!==(typeof(defaults)).toString()) {//typeof would not work in many situations 23 return defaults; 24 }*/ 25 var output=JSON.parse(JSON.stringify(input)),i; 26 for(i in defaults) { 27 output[i]=applyDefaults(input[i],defaults[i]); 28 } 29 output=JSON.parse(JSON.stringify(output)); 30 for(i in output) { 31 output[i]=applyDefaults(input[i],defaults[i]); 32 } 33 return output; 34 } 35 function def(str,v) { 36 Object.defineProperty(this,str,{get:function(){return v;}});// no changes to the varuble unless done internally via this core 37 } 38 39 (function(Learner) {//globaliser 40 /*Here we export the Learner.js's modules through various exporting formats*/ 41 if (typeof module!=="undefined") { 42 module=Learner;//for Node.js 43 }else if(typeof define!=="undefined"){ 44 define("Learner",function() { 45 return Learner;//for Require.js and similar tools (like Dojo) 46 }); 47 } 48 global.Learner=Learner;//For all web browsers (or the like) 49 })((function() {//definer 50 /*Here we define the first module: Learner at the end of this function we return Learner when it is ready, then it is handled by the above function.*/ 51 var Learner=function(e) { 52 /*This function builds base constructor. 53 e is the settings for this instance of Learner 54 */ 55 e=applyDefaults(e,this.defaults);// uses Learner.prototype.defaults for the defaults 56 this.cores[e.core].apply(this,e.coreSettings); 57 //passes e.coreSettings (Learner.prototype.defaults.coreSettings) into the core function that is specified in e.core (Learner.prototype.defaults.core) 58 this.core=e.core;//for debugging 59 }; 60 hide(Learner); 61 62 Learner.prototype={ 63 //Nothing core specific is defined here, excluding things in the .cores obj 64 constructor:Learner, 65 toString:ret(null), 66 toLocaleString:ret(null), 67 database:null, 68 defaults:{ 69 core:"default", //determines what core is being used 70 coreSettings:[], //passed into core function that is specified in the line above and are specific to the core, not the library in general 71 }, 72 cores:{ 73 /*All of the learning happens within these cores. 74 Each of these functions are only executed once per instalisation of the Learner object, and are expected to edit the "this" object, as they are executed using the apply function on the this object in the Learner constructor function. 75 The values passed into these functions are dependant on the documentation of each core, and can be entirely different, however, they must be able to handle the default core function values (found @ Learner.prototype.defaults.coreSettings) 76 Note that extensions of this library can add learning cores to this object. 77 */ 78 "default":function(e) { 79 e=applyDefaults(e,{ 80 thinkInterval:100,//the amount of time between each thought in milliseconds, as it is passed directly to the second argument of setTimeout(). If thinkInterval===false, the bot can't think before it does anything. 81 thinkFilter:function(input) { return "thought:"+input;},//an oppertunity to change the thought to a proper input format, if needed. 82 reinforcementDecay:0.875,//see "this.reinforcement" as defined in this core 83 reinforcementDecayLimit:0.5,//see "this.reinforcement" as defined in this core 84 actionMap:{//an array of all of the actions that the bot can take. Currently the bot can do naught but wonder 85 think:function(str) { 86 if (!this.thinkInterval) return; 87 setTimeout(function() {//this is so we don't get a stackoverflow error 88 this.action(this.thinkFilter(str)); 89 },this.thinkInterval); 90 }, 91 }, 92 }); 93 94 var selfEsteem=0,//The greater the number, the more self-esteem the bot is estimated to have. Negitive is a bad thing. Clearly shows depression. 95 myHistory=[],//a list of outputs that the bot has sent to a method in the action map 96 envHistory=[],//a list of enviromential updates 97 allHistory=[],//a list of all enviromential updates and outputs that the bot has sent to a method in the action map 98 words={};//all of the sub-strings that have a value asociated with them 99 100 //make all of these varubles acccesssable to the enviroment, but not changeable 101 def.call(this,'selfEsteem',selfEsteem);//as this number would be more usefull in the enviroment the underscores marking that it is internal is unneccicary 102 def.call(this,'__myHistory__',myHistory); 103 def.call(this,'__envHistory__',envHistory); 104 def.call(this,'__allHistory__',allHistory); 105 def.call(this,'__words__',words); 106 107 var action=function(e0) { 108 /*called on user action, or other enviromential changes*/ 109 e1=applyDefaults(e1,{ 110 val:"",//The string that will now be manipulated. 111 }); 112 //I am still working on this, and actually have forgotten some of what happens here. I do recall that it has two steps. 113 //Step 1:? <- I told you I forgot things. 114 }; 115 hide(action); 116 def.call(this,'action',action); 117 118 var reinforcement=function f(e1) { 119 /*user rewards or punishes (positive or negitive reinforcemnt)*/ 120 121 e1=applyDefaults(e1,{ 122 val:0,//the value to apply to each string and substring - <0 is a punishment >0 is a reward zero does nothing 123 reinforcementDecay:e.reinforcementDecay,//before working on an older string, "val" is multiplied by this number 124 reinforcementDecayLimit:e.reinforcementDecayLimit,//the limit for how close "val" can be to zero before aborting "recursive" history reinforcement 125 }); 126 127 var i,len,index,part;//prevents a varuble from being redefined at every iteration of a loop, these varubles will be defined via their first usage 128 129 this.selfEsteem+=e1.val;//this is where the self-esteem-related magic happens. To be honest, this is really jsut a way to proove that the bot has or hasn't been abused, by anyone. Including itself. 130 131 for (i=myHistory.length; (i>=0&&e1.val<e1.reinforcementDecayLimit); i--) {//every item in the output history, as long as the reinforcementDecayLimit allows, then leave the loop if the criteria doesn't fit anymore 132 133 for (len=(myHistory[i].length); len>1; len--){//the length of the sub-string 134 for (index=0; index<(myHistory[i].length-len); index++) {//the position of the sub-string 135 136 part=myHistory[i].substr(index,len);//this is the actual sub-string 137 138 /*if the sub-string has not been incountered before, make a spot for it to go*/ 139 if(typeof words[len]==="undefined"){//place for this length of sub-string 140 words[len]={}; 141 } 142 if(typeof words[len][part]==="undefined"){//the value itself 143 words[len][part]=el.val; 144 continue;//in this case it would be a waste of prossessing to set it to zero now then change it later, so set it now, then go on to the next sub-string 145 } 146 147 words[len][part]+=el.val;//this is where the value is actually changed 148 } 149 } 150 151 el.val*=e1.reinforcementDecay;//and thus it decays. 152 } 153 }; 154 hide(reinforcement); 155 def.call(this,'reinforcement',reinforcement); 156 }, 157 158 "__brickWall__":function(e) {//this can be used as a template for the more simple cores, but if this is an unsatisfactory example, look at the default core. 159 e=applyDefaults(e,{ 160 act:function(str) {//bot acts 161 console.log(str); 162 }, 163 }); 164 this.action=function(str) {//user acts 165 e.act(str); 166 }; 167 }, 168 169 //"deep":function() {}, 170 //"Q":function() {}, 171 }, 172 }; 173 return Learner; 174 })()); 175 176 })(this);