summaryrefslogtreecommitdiffstats
path: root/comm/suite/chatzilla/js/tests/DP.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--comm/suite/chatzilla/js/tests/DP.js612
1 files changed, 612 insertions, 0 deletions
diff --git a/comm/suite/chatzilla/js/tests/DP.js b/comm/suite/chatzilla/js/tests/DP.js
new file mode 100644
index 0000000000..5320b38c35
--- /dev/null
+++ b/comm/suite/chatzilla/js/tests/DP.js
@@ -0,0 +1,612 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Dissociated Press javascript for the jsbot
+ * see: http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?query=dissociated%20press
+ */
+
+DP_DEBUG = false;
+
+if (DP_DEBUG)
+ dpprint = dd;
+else
+ dpprint = (function () {});
+
+function CDPressMachine()
+{
+
+ this.wordPivots = new Object();
+ this.cleanCounter = 0;
+ this.cleanCount = 0;
+
+}
+
+CDPressMachine.CLEAN_CYCLE = 1000; // list will be trimmed after this many
+ // or never if < 1 addPhrase()s
+CDPressMachine.CLEAN_THRESHOLD = 2; // anything <= this will be trimmed
+CDPressMachine.RANDOMIZE_DEPTH = 10; // not used yet
+CDPressMachine.MIN_PHRASE_LENGTH = 3; // requested minimum phrase length
+CDPressMachine.MAX_PHRASE_LENGTH = 8; // requested maximum phrase length
+CDPressMachine.LENGTH_RETRIES = 3 // number of retries per word
+ // (to reach maxlen)
+CDPressMachine.WORD_PATTERN = /[\x21-\x7e]+/; // pattern for words
+
+/**
+ * Adds a phrase to the engine
+ */
+CDPressMachine.prototype.addPhrase =
+function DPM_addPhrase (strPhrase, weight)
+{
+ if (strPhrase == "")
+ return;
+
+ this.cleanCounter++;
+ if ((CDPressMachine.CLEAN_CYCLE >= 1) &&
+ (this.cleanCounter >= CDPressMachine.CLEAN_CYCLE))
+ {
+ dpprint ("** cleaning list");
+
+ this.cleanCounter = 0;
+ this.trimList (CDPressMachine.CLEAN_THRESHOLD);
+ this.cleancount++;
+ }
+
+ strPhrase = strPhrase.toLowerCase();
+
+ /* split the phrase */
+ var aryWordMatches = strPhrase.split (" ");
+ var previousWord = aryWordMatches[aryWordMatches.length - 1];
+ previousWord = previousWord.match(CDPressMachine.WORD_PATTERN);
+ var nextWord = "";
+
+ /* loop through each word */
+ for (var i=-1; i < aryWordMatches.length; i++)
+ {
+ var currentWord = nextWord;
+ var currentWordPivot = this.wordPivots[currentWord];
+
+ if (typeof currentWordPivot == "undefined")
+ currentWordPivot =
+ (this.wordPivots[currentWord] = new CWordPivot (currentWord));
+
+ currentWordPivot.previousList.addLink (previousWord, weight);
+
+ if (i < aryWordMatches.length - 1)
+ {
+ nextWord = aryWordMatches[i + 1];
+ if (nextWord == (String.fromCharCode(1) + "action"))
+ nextWord = escape(nextWord.toUpperCase());
+ else
+ nextWord = nextWord.match(CDPressMachine.WORD_PATTERN);
+
+ if (nextWord == null)
+ nextWord = ""; //this is weak
+
+ currentWordPivot.nextList.addLink (nextWord, weight);
+ }
+ else
+ currentWordPivot.nextList.addLink ("");
+
+ previousWord = currentWord;
+
+ }
+
+}
+
+CDPressMachine.prototype.addPhrases =
+function DPM_addPhrases(phrases)
+{
+
+ for (var i in phrases)
+ this.addPhrase (phrases[i]);
+
+}
+
+/**
+ * Gets a phrase from the engine, starting from seedWord.
+ * if dir is greater than 0, then seedWord will be the first in
+ * the phrase, otherwise it will be the last
+ */
+CDPressMachine.prototype.getPhraseDirected =
+function DPM_getPhraseDirected(seedWord, dir)
+{
+ var word = (typeof seedWord != "undefined") ? seedWord : "";
+ var tempword = word;
+ var rval = "";
+ var c = 0, retry = 0;
+
+ dpprint ("DPM_getPhraseDirected: '" + word + "' " + dir);
+
+ if (typeof this.wordPivots[word] == "undefined")
+ return;
+
+ do
+ {
+ if (typeof this.wordPivots[word] == "undefined")
+ {
+ dd ("** DP Error: Word '" + word + "' is not a pivot **");
+ return;
+ }
+
+ if (dir > 0) // pick a word
+ word= this.wordPivots[word].nextList.getRandomLink().link;
+ else
+ word= this.wordPivots[word].previousList.getRandomLink().link;
+
+ if (word != "") // if it isn't blank
+ {
+ dpprint ("DPM_getPhraseDirected: got word '" + word + "'");
+
+ if (c < CDPressMachine.MIN_PHRASE_LENGTH)
+ retry = 0;
+
+ if (c > CDPressMachine.MAX_PHRASE_LENGTH)
+ if (((dir > 0) && (this.wordPivots[word].nextList.list[""])) ||
+ ((dir <= 0) &&
+ (this.wordPivots[word].previousList.list[""])))
+ {
+ dpprint ("DPM_getPhraseDirected: forcing last word");
+ word="";
+ rval = rval.substring (0, rval.length - 1);
+ break;
+ }
+
+ if (dir > 0)
+ rval += word + " "; // put it in the rslt
+ else
+ rval = word + " " + rval;
+
+ c++; // count the word
+ }
+ else // otherwise
+ {
+ dpprint ("DPM_getPhraseDirected: last word");
+ // if it's too short
+ // and were not out of retrys
+ if ((c < CDPressMachine.MIN_PHRASE_LENGTH) &&
+ (retry++ < CDPressMachine.LENGTH_RETRIES))
+ word = tempword; // try again
+ else
+ // otherwise, we're done
+ rval = rval.substring (0, rval.length - 1);
+ }
+
+ tempword = word;
+
+ } while (word != "");
+
+ rval = unescape (rval);
+
+ return rval;
+
+}
+
+CDPressMachine.prototype.getPhraseForward =
+function DPM_getPhraseForward(firstWord)
+{
+ return this.getPhraseDirected (firstWord, 1)
+}
+
+CDPressMachine.prototype.getPhraseReverse =
+function DPM_getPhraseReverse(lastWord)
+{
+ return this.getPhraseDirected (lastWord, -1)
+}
+
+/**
+ * locates a random pivot by following CDPressMachine.RANDOMIZE_DEPTH
+ * links from |word|.
+ */
+CDPressMachine.prototype.getRandomPivot =
+function DPM_getRandomPivot (word)
+{
+
+ /**
+ * XXXrgg: erm, this is currently pointless, but could be neat later
+ * if max phrase length's were implemented.
+ */
+ if (false)
+ {
+ var depth = parseInt (Math.round
+ (CDPressMachine.RANDOMIZE_DEPTH * Math.random()));
+ word = "";
+ for (var i = 0;
+ i < depth, word =
+ this.wordPivots[word].nextList.getRandomLink().link;
+ i++); /* empty loop */
+
+ }
+
+}
+
+CDPressMachine.prototype.getPhrase =
+function DPM_getPhrase(word)
+{
+ var rval = this.getPhraseContaining (word);
+
+ return rval;
+
+}
+
+/**
+ * Returns a phrase with |word| somewhere in it.
+ */
+CDPressMachine.prototype.getPhraseContaining =
+function DPM_getPhraseContaining(word)
+{
+ if (typeof word == "undefined")
+ word = "";
+ else
+ word = word.toString();
+
+ dpprint ("* DPM_getPhraseContaining: '" + word + "'");
+
+ var rval, spc;
+ var post, pre = this.getPhraseReverse (word);
+ if (word != "")
+ var post = this.getPhraseForward (word);
+
+ dpprint ("* DPM_getPhraseContaining: pre = '" + pre + "' post = '" +
+ post + "'");
+ dpprint ("* DPM_getPhraseContaining: " + (post == "" && pre == ""));
+
+ if (word)
+ {
+ word = unescape (word);
+ spc = " ";
+ }
+ else
+ spc = "";
+
+ if (pre)
+ {
+ if (post)
+ rval = pre + spc + word + spc + post;
+ else
+ rval = pre + spc + word;
+ }
+ else
+ {
+ if (post)
+ rval = word + spc + post;
+ else
+ if (post == "" && pre == "")
+ rval = word;
+ }
+
+ if (rval && (rval.charCodeAt(0) == 1))
+ rval += String.fromCharCode(1);
+
+ dpprint ("* DPM_getPhraseContaining: returning '" + rval + "'");
+
+ return rval;
+
+}
+
+CDPressMachine.prototype.getPhraseWeight =
+function DPM_getPhraseWeight (phrase)
+{
+ var ary = this.getPhraseWeights (phrase);
+ var w = 0;
+
+ while (ary.length > 0)
+ w += ary.pop();
+
+ return w;
+}
+
+CDPressMachine.prototype.getPhraseWeights =
+function DPM_getPhraseWeights (phrase)
+{
+ var words, ary = new Array();
+ var lastword = "";
+ var link, pivot;
+
+ if (!phrase)
+ return ary;
+
+ words = phrase.split (" ");
+
+ for (var i = 0; i < words.length; i++)
+ {
+
+ if (i == 0)
+ {
+ lastWord = "";
+ nextWord = words[i + 1];
+ }
+ else if (i == words.length - 1)
+ {
+ lastWord = words[i - 1];
+ nextWord = "";
+ }
+ else
+ {
+ lastWord = words[i - 1];
+ nextWord = words[i + 1];
+ }
+
+ pivot = this.wordPivots[words[i]];
+
+ if (pivot)
+ {
+ link = pivot.previousList.list[lastWord];
+
+ if (link)
+ ary.push(link.weight);
+ else
+ ary.push(0);
+
+ link = pivot.nextList.list[nextWord];
+
+ if (link)
+ ary.push(link.weight);
+ else
+ ary.push(0);
+ }
+ else
+ {
+ ary.push(0);
+ ary.push(0);
+ }
+
+ }
+
+ return ary;
+
+}
+
+CDPressMachine.prototype.getPivot =
+function DPM_getPivot(word)
+{
+
+ return this.wordPivots[word];
+
+}
+
+CDPressMachine.prototype.trimList =
+function DPM_trimList(threshold)
+{
+ var el;
+ var c;
+
+ for (el in this.wordPivots)
+ {
+ c = this.wordPivots[el].nextList.trimList (threshold);
+ if (c == 0)
+ delete this.wordPivots[el];
+ else
+ {
+ c = this.wordPivots[el].previousList.trimList (threshold);
+ if (c == 0)
+ delete this.wordPivots[el];
+ }
+
+ }
+
+}
+
+CDPressMachine.prototype.getMachineStatus =
+function DPM_getMachineStatus()
+{
+ var o = new Object();
+
+ o.pivotcount = 0;
+ o.linkcount = 0;
+ o.linksperpivot = 0;
+ o.maxweight = 0;
+ o.minweight = Number.MAX_VALUE;
+ o.averageweight = 0;
+ o.cleancounter = this.cleanCounter;
+ o.cleancount = this.cleanCount;
+
+ for (var pivot in this.wordPivots)
+ {
+ o.pivotcount++;
+
+ for (var link in this.wordPivots[pivot].previousList.list)
+ {
+ var l = this.wordPivots[pivot].previousList.list[link];
+
+ o.linkcount++;
+
+ o.maxweight = Math.max (o.maxweight, l.weight);
+ o.minweight = Math.min (o.minweight, l.weight);
+
+ (o.averageweight == 0) ?
+ o.averageweight = l.weight :
+ o.averageweight = (l.weight + o.averageweight) / 2;
+
+ }
+ }
+
+ o.linksperpivot = o.linkcount / o.pivotcount;
+
+ return o;
+
+}
+
+////////////////////////
+function CWordPivot (word)
+{
+
+ dpprint ("* new pivot : '" + word + "'");
+ this.word = word;
+ this.nextList = new CPhraseLinkList(word, "next");
+ this.previousList = new CPhraseLinkList(word, "previous");
+
+}
+
+///////////////////////
+
+function CPhraseLinkList (parentWord, listID)
+{
+
+ if (DP_DEBUG)
+ {
+ this.parentWord = parentWord;
+ this.listID = listID;
+ }
+
+ this.list = new Object();
+
+}
+
+CPhraseLinkList.prototype.addLink =
+function PLL_addLink (link, weight)
+{
+ var existingLink = this.list[link];
+
+ dpprint ("* adding link to '" + link + "' from '" + this.parentWord +
+ "' in list '" + this.listID + "'");
+
+ if (typeof weight == "undefined")
+ weight = 1;
+
+ if (typeof existingLink == "undefined")
+ this.list[link] = new CPhraseLink (link, weight);
+ else
+ if (!(typeof existingLink.adjust == "function"))
+ dd("existingLink.adjust is a '" + existingLink.adjust + "' " +
+ "not a function! link is '" + link +"'");
+ else
+ existingLink.adjust (weight);
+
+}
+
+CPhraseLinkList.prototype.getRandomLink =
+function PLL_getRandomLink ()
+{
+ var tot = 0;
+ var lastMatch = "";
+ var aryChoices = new Array();
+ var fDone = false;
+
+ dpprint ("* PLL_getRandomLink: from '" + this.parentWord + "'");
+
+ for (el in this.list)
+ {
+ tot += this.list[el].weight;
+
+ for (var i = 0; i< aryChoices.length; i++)
+ if (this.list[el].weight <= aryChoices[i].weight)
+ break;
+
+ arrayInsertAt (aryChoices, i, this.list[el]);
+ }
+
+ if (DP_DEBUG)
+ for (var i = 0; i < aryChoices.length; i++)
+ dpprint ("** potential word '" + aryChoices[i].link + "', weight " +
+ aryChoices[i].weight);
+
+ var choice = parseInt (Math.round(((tot - 1) * Math.random()) + 1));
+
+ dpprint ("* PLL_getRandomLink: tot = " + tot + ", choice = " + choice);
+
+ tot = 0;
+ for (i = 0; i < aryChoices.length; i++)
+ {
+ if ((tot += aryChoices[i].weight) >= choice)
+ {
+ lastMatch = aryChoices[i];
+ break;
+ }
+ }
+
+ if (lastMatch == "")
+ lastMatch = aryChoices[aryChoices.length - 1];
+
+ if (!lastMatch)
+ lastMatch = {link: ""}
+
+ dpprint ("* PLL_getRandomLink: returning: " + lastMatch);
+
+ return lastMatch;
+
+}
+
+CPhraseLinkList.prototype.getListWeights =
+function PLL_getListWeights ()
+{
+ var ary = new Array();
+
+ for (var el in this.list)
+ ary.push (this.list[el].weight);
+
+ return ary;
+
+}
+
+CPhraseLinkList.prototype.getListLinks =
+function PLL_getListLinks ()
+{
+ var ary = new Array();
+
+ for (var el in this.list)
+ ary.push (this.list[el].link);
+
+ return ary;
+
+}
+
+CPhraseLinkList.prototype.trimList =
+function PLL_trimList (threshold)
+{
+ var el;
+ var c;
+
+ dpprint ("trimming '" + this.parentWord + "'s list to " + threshold);
+
+ for (el in this.list)
+ {
+ c++;
+
+ if (this.list[el].weight <= threshold)
+ {
+ dpprint ("removing '" + el + "' from '" + this.parentWord + "'s '" +
+ this.listID + "' list, because it's weight is " +
+ this.list[el].weight);
+
+ delete this.list[el];
+ c--;
+ }
+ }
+
+ return c;
+
+}
+
+////////////////////////
+
+function CPhraseLink (link, weight)
+{
+ if (typeof weight == "undefined")
+ this.weight = 1;
+ else
+ this.weight = weight;
+
+ this.link = link;
+
+}
+
+CPhraseLink.prototype.adjust =
+function PL_adjust(weight)
+{
+
+ if ((this.weight += weight) < 1)
+ this.weight = 1;
+
+}
+
+CPhraseLink.prototype.weight =
+function PL_weight ()
+{
+
+ return this.weight;
+
+}