changeset 6:98935af12b04

Debugged the recursive part of the parsing algorithm, so it now recognizes multiple prepositions in any order. Still some bugs.
author jonathandicarlo@jonathan-dicarlos-macbook-pro.local
date Wed, 14 May 2008 13:25:17 -0700
parents a049cb93db46
children aab0d14248f5
files hip.html hip.js
diffstat 2 files changed, 66 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/hip.html	Tue May 13 18:57:55 2008 -0700
+++ b/hip.html	Wed May 14 13:25:17 2008 -0700
@@ -8,6 +8,7 @@
   <title></title>
 </head>
 <body>
+  <div id="status-line">Ubiquity!</div>
   <input id="search-box" type="text" size="40" />
   <div id="autocomplete-popup"></div>
 </body>
--- a/hip.js	Tue May 13 18:57:55 2008 -0700
+++ b/hip.js	Wed May 14 13:25:17 2008 -0700
@@ -1,3 +1,14 @@
+function dictDeepCopy( dict ) {
+  var newDict = {};
+  for (var i in dict ) {
+    newDict[i] = dict[i];
+  }
+  return newDict;
+};
+
+function dictKeys( dict ) {
+  return [ key for ( key in dict ) ];
+}
 
 function NounType( name, expectedWords ) {
     this._init( name, expectedWords );
@@ -44,6 +55,7 @@
 
 var anyWord = {
   // a singleton object which can be used in place of a NounType.
+ _name: "text",
  match: function( fragment ) {
     return true;
   },
@@ -64,7 +76,20 @@
   },
 
  getCompletionText: function() {
-    // returns completed and canonicalized sentence
+    // return plain text that we should set the input box to if user hits
+    // space bar on this sentence.
+    var sentence = this._verb._name;
+    if ( this._DO ) {
+      sentence = sentence + " " + this._DO;
+    }
+    for ( var x in this._modifiers ) {
+      sentence = sentence + " " + x + " " + this._modifiers[x];
+    }
+    return sentence;
+  },
+
+ getDisplayText: function() {
+    // returns html formatted sentence for display in suggestion list
     var sentence = this._verb._name;
     if ( this._verb._DOType ) {
       if ( this._DO ) {
@@ -74,11 +99,11 @@
       }
     }
 
-    for ( var x in this._verb._modifiers ) {
+    for ( var x in this._verb._modifiers ) {  // was this._verb._modifiers
       if ( this._modifiers[ x ] ) {
-	sentence = sentence + " " + x + " " + this._modifiers[x];
+	sentence = sentence + " <b>" +  x + " " + this._modifiers[x] + "</b>";
       } else {
-	sentence = sentence + " <span class=\"needarg\">(" + this._verb._modifiers[x]._name + ")</span>";
+	sentence = sentence + " <span class=\"needarg\">(" + x + " " + this._verb._modifiers[x]._name + ")</span>";
       }
     }
     return sentence;
@@ -86,6 +111,7 @@
 
  getDescription: function() {
     // returns a string describing what the sentence will do if executed
+    return this._verb.getDescription( this._DO, this._modifiers );
   }
 
 };
@@ -106,12 +132,17 @@
     // example:  { "from" : City, "to" : City, "on" : Day }
   },
 
+ getDescription: function() {
+    // returns a string describing what the sentence will do if executed
+    return this._verb.getDescription( this._DO, this._modifiers );
+  }
+
  recursiveParse: function( unusedWords, filledMods, unfilledMods ) {
     var x;
     var suggestions = [];
     var completions = [];
     var directObject = "";
-    if ( [key for (key in unfilledMods)].length == 0 ) {
+    if ( dictKeys( unfilledMods ).length == 0 ) {
       // Done with modifiers, try to parse direct object.
       if ( unusedWords.length == 0 ) {
 	// No words left, no direct object.  Try parsing sentence
@@ -141,14 +172,11 @@
 	  return [];
 	}
       }
-    } 
-  },
-
- /*
-   else {
+    } else {
       // "pop" a preposition off of the properties of unfilledMods
-      var preposition = [key for (key in unfilledMods)][0];
-      var newUnfilledMods = unfilledMods.splice();
+      var preposition = dictKeys( unfilledMods )[0];
+      // newUnfilledMods is the same as unfilledMods without preposition
+      var newUnfilledMods = dictDeepCopy( unfilledMods );
       delete newUnfilledMods[preposition];
 
       // Look for a match for this preposition
@@ -156,7 +184,7 @@
       var matchIndices = [];
       for ( var x = 0; x < unusedWords.length - 1; x++ ) {
 	if ( preposition.indexOf( unusedWords[x] ) == 0 ) {
-	  if ( nounType.match( unusedWords[ x + 1 ] ) == 0 ) {
+	  if ( nounType.match( unusedWords[ x + 1 ] ) ) {
 	    // Match for the preposition at index x followed by
 	    // an appropriate noun at index x+1
 	    matchIndices.push( x );
@@ -167,31 +195,33 @@
 	// no match for this preposition.
 	// Leave it blank and try to parse the rest:
 	filledMods[preposition] = "";
-	return recursiveParse( unusedWords, filledMods, newUnfilledMods );
+	var directObject = unusedWords.join( " " );
+	return [ new ParsedSentence( this, directObject, filledMods ) ];
+	//return this.recursiveParse( unusedWords, filledMods, newUnfilledMods );
       } else {
+	// this is placeholder, destroy it.
 	for ( x in matchIndices ) {
-	  // remove the words that matched the preposition and following
-	  // noun:
 	  var noun = unusedWords[ matchIndices[x]+1 ];
 	  var newUnusedWords = unusedWords.slice();
-	  newUnusedWords.splice( possibilities[x], 2 );
-	  // add every noun completion from every possibility...
+	  newUnusedWords.splice( matchIndices[x], 2 );
+	  var directObject = newUnusedWords.join( " " );
+
 	  suggestions = nounType.suggest( noun );
 	  for ( var y in suggestions ) {
-	    var newFilledMods = filledMods.slice();
+	    var newFilledMods = dictDeepCopy( filledMods );
 	    newFilledMods[ preposition ] = suggestions[y];
-	    var newCompletions = recursiveParse( newUnusedWords,
-						 newFilledMods,
-						 newUnfilledMods );
+	    var newCompletions = this.recursiveParse( newUnusedWords,
+						      newFilledMods,
+						      newUnfilledMods );
 	    completions = completions.concat( newCompletions );
 	  }
 	}
 	return completions;
-      }
+      } 
     }
-    }, */
+  },
 
- parse: function( words ) {
+ getCompletions: function( words ) {
     /* returns a list of ParsedSentences. */
     /* words is an array of words that were space-separated.
        The first word, which matched this verb, has already been removed.
@@ -203,11 +233,6 @@
     return this.recursiveParse( words, {}, this._modifiers );
   },
 
- getCompletions: function( words ) {
-    var sentences = this.parse( words );
-    return [ sentences[x].getCompletionText() for ( x in sentences ) ];
-  },
-
  match: function( sentence ) {
     // returns a float from 0 to 1 telling how good of a match the input
     // is to this verb.
@@ -254,7 +279,7 @@
  _init: function( ) {
     this._lockedInSentence = null;
     this._hilitedSuggestion = 0;
-    this._suggestionList = [];
+    this._suggestionList = []; // a list of ParsedSentences.
   },
  
  updateSuggestionList: function( query ) {
@@ -267,12 +292,13 @@
 	completions = verb.getCompletions( words.slice(1) );
 	this._suggestionList = this._suggestionList.concat( completions );
       }
-    } // TODO sort in order of match quality
+    }
+    // TODO sort in order of match quality
     this._hilitedSuggestion = 0;
   },
 
- getSuggestions : function() {
-    return this._suggestionList;
+ getSuggestionsAsHtml : function() {
+    return [ this._suggestionList[x].getDisplayText() for ( x in this._suggestionList ) ];
   },
 
  indicationDown: function( ) {
@@ -297,7 +323,7 @@
  autocomplete: function( query ) {
     var hilited = this.getHilitedSuggestion();
     if ( hilited > -1 ) {
-      var newText = this._suggestionList[ hilited ] + " ";
+      var newText = this._suggestionList[ hilited ].getCompletionText() + " ";
     } else {
       newText = query;
     }
@@ -330,7 +356,7 @@
 }
 
 function updateDisplay( ) {
-   var suggestions = gQs.getSuggestions();
+   var suggestions = gQs.getSuggestionsAsHtml();
    var hilitedSuggestion = gQs.getHilitedSuggestion();
    var ac = $("#autocomplete-popup");
    ac.html( makeSuggestionHtml( "div", suggestions, hilitedSuggestion ) );
@@ -377,6 +403,7 @@
 }
 
 $(document).ready( function() {
+    $("#status-line").html( "Welcome to Ubiquity." );
     $("#search-box").focus();
     $("#search-box").keyup( searchBoxQuery );
     $("#autocomplete-popup").css(
@@ -386,6 +413,7 @@
 });
 
 /* Minor problems:
-1. verbs with indirect objects are returning empty completion lists
 2. multiple word direct objects are truncated to single word
+3. prepositional phrases past the first don't get matched?
+4. sentences need to have descriptions
 */