_binary From 84dd0eb74ea963050b6759cc2e563445a7663238 Mon Sep 17 00:00:00 2001
From: Akshat Kukreti <akshatkukreti@gmail.com>
Date: Tue, 14 Aug 2012 18:00:21 -0700
Subject: [PATCH] Italian stemmer added

---
 locale/it/resources/tokenizer.php |  603 ++++++++++++++++++++++++++++++++++++-
 tests/ItStemmer_test.php          |  128 ++++++++
 2 files changed, 727 insertions(+), 4 deletions(-)
 create mode 100644 tests/ItStemmer_test.php

diff --git a/locale/it/resources/tokenizer.php b/locale/it/resources/tokenizer.php
index d5e4732..1a44e83 100755
--- a/locale/it/resources/tokenizer.php
+++ b/locale/it/resources/tokenizer.php
@@ -1,4 +1,4 @@
-<?php
+﻿<?php
 /** 
  *  SeekQuarry/Yioop --
  *  Open Source Pure PHP Search Engine, Crawler, and Indexer
@@ -36,10 +36,605 @@ if(!defined('BASE_DIR')) {echo "BAD REQUEST"; exit();}
  * either contains a stemmer for the language in question or
  * it specifies how many characters in a char gram
  *
- * @author Chris Pollett
+ * @author Akshat Kukreti
  * @package seek_quarry
  * @subpackage locale
  */
 
-$CHARGRAMS['it'] = 5;
-?>
+class ItStemmer
+{
+    //Contains the stem for the word
+    static $buffer;
+	
+	//Starting index of region R1
+	static $r1_start;
+	
+	//Starting index of region R2
+	static $r2_start;
+	
+	//Starting index of region RV
+	static $rv_start;
+
+    //Region R1
+    static $r1_string;
+	
+	//Region R2
+    static $r2_string;
+	
+	//Region RV
+    static $rv_string;
+	
+	//Holds true if step1 made any changes to the stem
+	static $step1_changes;
+	
+	/*Function stem computes the stem of a word in the Italian language
+	 *Example guardando,guardandogli,guardandola,guardano all stem to guard
+	 *
+	 *@param string $word is the word to be stemmed
+	 *@return string stem of $word
+     */
+    static function stem($word)
+    { 	
+        self::$buffer = $word;
+		self::$step1_changes = false;
+		
+		//Get R1,R2 and RV
+		self::getRegions();
+			
+		self::prelude();
+		self::step0();
+		self::step1();
+		self::step2();
+		self::step3a();
+		self::step3b();
+		self::postlude();
+		
+		return self::$buffer;
+    }
+	
+	/*Function checkForSuffix checks if a string is a suffix for another string
+	 *
+	 *@param $parent_string is the string in which we wish to find the suffix 
+	 *@param $substring is the suffix we wish to check
+	 *@return $pos as the starting position of the suffix $substring in 
+	 *$parent_string if it exists, else false
+	 */ 
+	static function checkForSuffix($parent_string,$substring)
+	{
+        $pos = strrpos($parent_string,$substring);
+        if($pos !== false && 
+		   (strlen($parent_string) - $pos == strlen($substring)))
+            return $pos;
+        else
+            return false;
+	}		
+	
+	/*Function in checks if a string occurs in another string
+	 *
+	 *@param $string is the parent string
+	 *@param $substring is the string checked to be a sub-string of $string
+     *@return true if $substring is a substring of $string, false otherwise	 
+	 */
+	static function in($string,$substring)
+	{
+        $pos = strpos($string,$substring);
+	    if($pos !== false)
+	        return true;
+	    else
+	        return false;
+    }
+	
+	/*Function r1 returns the starting index for region R1
+	 *
+	 *@param $string is the string for which we wish to find the index
+	 *@return $r1_start as the starting index for R1 for $string
+	 */
+	static function r1($string)
+    {
+       $r1_start = -1;
+       for($i = 0;$i < strlen($string);$i++){
+           if($i >= 1){
+		       if(self::isVowel($string[$i - 1]) && 
+			      !self::isVowel($string[$i])){
+                   $r1_start = $i + 1;
+			        break;
+			    }	
+		    }	
+        }
+    
+        if($r1_start > strlen($string) - 1)
+            return -1;
+        else
+            return $r1_start;	
+    }
+    
+    /*Function r2 returns the starting index for region R2
+	 *
+	 *@param $string is the string for which we wish to find the index
+	 *@return $r2_start as the starting index for R1 for $string
+	 */	
+	static function r2($string)
+    {
+        $r2_start = -1;
+        $r1_start = self::r1($string);
+	
+	    if($r1_start !== -1){
+	        for($i = $r1_start; $i < strlen($string); $i++){
+	            if($i >= $r1_start + 1){
+		            if(self::isVowel($string[$i-1]) && 
+					   !self::isVowel($string[$i])){
+                        $r2_start = $i + 1;
+                        break;
+			        }	
+		        }
+            }
+	    }	
+	
+	    if($r2_start > strlen($string) - 1)
+	        return -1;
+	    else
+	        return $r2_start;
+    }
+	
+	/*Function rv returns the starting index for region RV
+	 *
+	 *@param $string is the string for which we wish to find the index
+	 *@return $rv_start as the starting index for RV for $string
+	 */
+	static function rv($string)
+	{
+	    $i = 0;
+		$j = 1;
+		$rv_start = -1;
+		
+		/*If the second letter is a consonant, RV is the region after the 
+		 *next following vowel
+		 */
+		if(!self::isVowel($string[$j])){
+            for($k = 2; $k <strlen($string) ; $k++){
+                if(self::isVowel($string[$k])){
+                    $rv_start = $k + 1;
+                    break;
+                }
+            }
+        }			
+		
+        /*If the first two letters are vowels, RV is the region after the next
+         *consonant
+         */		 
+		else if(self::isVowel($string[$i]) && self::isVowel($string[$j])){
+            for($k = 2; $k <strlen($string) ; $k++){
+                if(!self::isVowel($string[$k])){
+                    $rv_start = $k + 1;
+                    break;
+                }
+            }
+        }
+		
+		//Consonant-vowel case,RV is the region after the third letter
+		else if(!self::isVowel($string[$i]) && self::isVowel($string[$j])){
+            $rv_start = 3;
+        }
+		
+		return $rv_start;
+    }
+	
+	/*Function getRegions determines the regions R1, R2 and RV in the form
+	 *strings. $r1_string, $r2_string, $r3_string for R1,R2 and R3 
+	 *repectively
+	 */
+	static function getRegions()
+	{
+	    if((self::$r1_start = self::r1(self::$buffer)) != -1)
+	        self::$r1_string = substr(self::$buffer,self::$r1_start);
+	    else 
+	        self::$r1_string = null;
+	    if((self::$r2_start = self::r2(self::$buffer)) != -1)	
+	        self::$r2_string = substr(self::$buffer,self::$r2_start);
+	    else 
+	        self::$r2_string = null;	
+	    if((self::$rv_start = self::rv(self::$buffer)) != -1)	
+	        self::$rv_string = substr(self::$buffer,self::$rv_start);
+	    else 
+	        self::$rv_string = null;
+	}
+	
+	/*Function isVowel checks if a character is a vowel or not
+	 *
+	 *@param $char is the character to be checked
+	 *@return true if $char is a vowel, false otherwise
+	 */
+	static function isVowel($char)
+    {
+        switch($char)
+	    {
+            case "U": case "I":
+			    return false;
+	        
+			case "a": case "e": case "i": case "o": case "u":
+		    case "à": case "è": case "ì": case "ò": case "ù":
+		        return true;
+	    }
+    }
+	
+	/*Function maxSuffix returns the longest suffix for a given string
+	 *
+	 *@param $string is the for which the maximum suffix is to be found
+	 *@param $suffixes is an array of suffixes
+	 *@return $max_suffix is the longest suffix for $string
+	 */
+	static function maxSuffix($string,$suffixes)
+    {
+        $max_length = 0;
+        $max_suffix = null;
+	
+	    foreach($suffixes as $suffix){
+	        $pos = strpos($string,$suffix);
+	        if($pos !== false){
+	            $string_tail = substr($string,$pos);
+	            $suffix_length = strlen($suffix);
+	            if(!strcmp($string_tail,$suffix)){
+		            if($suffix_length > $max_length){
+			            $max_suffix = $suffix;
+				        $max_length = $suffix_length;
+					}	
+                }
+            }
+        }		
+        
+		return $max_suffix;
+    }
+	
+	/*Function acuteByGrave replaces all acute accents in a string by grave
+	 *accents
+	 *
+	 *@param $string is the string from in which the acute accents are to be
+	 *replaced
+	 *@return $string with changes
+	 */
+	static function acuteByGrave($string)
+    {
+        $pattern_array = Array("/á/","/é/","/í/","/ó/","/ú/");
+        $replacement_array = Array("a","e","i","o","u");
+        $string = preg_replace($pattern_array,$replacement_array,$string);     
+        return($string);  
+    }
+	
+	/*Function prelude performs the following functions
+	 *Replace acute accents with grave accents
+	 *Mark u after q and u,i preceded and followed by a vowel as a non vowel
+	 *by converting to upper case
+	 */
+	static function prelude()
+    {
+        $pattern_array = Array("/Qu/","/qu/");
+        $replacement_array = Array("QU","qU");
+	
+	    //Replace acute accents by grave accents
+	    self::$buffer = self::acuteByGrave(self::$buffer);
+	
+	    /*Convert u preceded by q and u,i preceded and followed by vowels
+         *to upper case to mark them as non vowels
+         */	 
+	    self::$buffer = preg_replace($pattern_array,$replacement_array,
+		               self::$buffer);   
+	    for($i = 0; $i < strlen(self::$buffer) - 1; $i++){
+	        if($i >= 1 && (self::$buffer[$i] == "i" || 
+			               self::$buffer[$i] == "u")){
+		        if(self::isVowel(self::$buffer[$i-1]) && 
+				   self::isVowel(self::$buffer[$i+1]))
+			        self::$buffer[$i] = strtoupper(self::$buffer[$i]);
+		    }
+        }
+    }
+	
+	//Function step0: Attached pronoun
+	static function step0()
+    {
+        $max = 0;
+	    $max_suffix = null;
+        $suffixes = Array("ci","gli","la","le","li","lo",
+	                  "mi","ne","si","ti","vi","sene",
+					  "gliela","gliele","glieli","glielo",
+					  "gliene","mela","mele","meli","melo",
+					  "mene","tela","tele","teli","telo",
+					  "tene","cela","cele","celi","celo",
+					  "cene","vela","vele","veli","velo","vene");
+	    $phrases = Array("ando","endo","ar","er","ir");
+	
+	    //Find the maximum length suffix in the string
+	    $max_suffix = self::maxSuffix(self::$rv_string,$suffixes);
+	
+        if($max_suffix != -1){
+            $sub_string = substr(self::$rv_string,0,-strlen($max_suffix));	
+	        foreach($phrases as $phrase){
+		        if(self::checkForSuffix($sub_string,$phrase)){
+		            switch($phrase)
+				    {
+			            case "ando": case "endo":
+				            self::$buffer = str_replace($max_suffix,"",
+							               self::$buffer);
+				            break;
+				        case "ar": case "er": case "ir":
+		                    self::$buffer = str_replace($max_suffix,"e",
+						                   self::$buffer);
+			        }
+		        }
+	        }
+        }	
+    }
+	
+	//Function step1: Standard suffix removal
+	function step1()
+    {
+        $suffixes = Array("anza","anze","ico","ici","ica",
+	                      "ice","iche","ichi","ismo","ismi",
+					      "abile","abili","ibile","ibili","ista",
+					      "iste","isti","istà","istè","istì",
+					      "oso","osi","osa","ose","mente","atrice",
+					      "atrici","ante","anti","azione","azioni",
+					      "atore","atori","logia","logie","uzione",
+					      "uzioni","usione","usioni","enza","anze",
+					      "amento","amenti","imento","imenti","amente",
+					      "ità","ivo","ivi","iva","ive");
+						  
+		//Get R1,R2 and RV
+        self::getRegions();
+	
+        //Find the longest suffix
+	    $max_suffix = self::maxSuffix(self::$buffer,$suffixes);
+	
+	    //Handle suffix according
+	    switch($max_suffix)
+	    {
+	        
+		    case "anza": case "anze": case "ico": case "ici": case "ica": 
+		    case "ice": case "iche": case "ichi": case "ismo": case "ismi":   
+		    case "abile": case "abili": case "ibile": case "ibili": case "ista":   
+		    case "iste": case "isti": case "istà": case "istè": case "istì":   
+		    case "oso": case"osi": case "osa": case "ose": case "mente":   
+		    case "atrice": case "atrici": case "ante": case "anti":
+            
+                //Delete if in R2			
+	            if(self::in(self::$r2_string,$max_suffix)){
+	                self::$buffer = str_replace($max_suffix,"",self::$buffer);
+	                self::$step1_changes = true;
+	            }
+                break;
+
+            case "azione": case "azioni": case "atore": case "atori":		
+
+	            //Delete if in R2
+	            if(self::in(self::$r2_string,$max_suffix)){
+	                self::$buffer = str_replace($max_suffix,"",self::$buffer);
+	                self::$step1_changes = true;
+	            }	
+	            //If preceded by ic, delete if in R2
+	            if(self::checkForSuffix(self::$buffer,"ic")){
+	                if(self::in(self::$r2_string,"ic")){
+	                    self::$buffer = str_replace("ic","",self::$buffer);
+	                    self::$step1_changes = true;
+		            }
+	            }
+			    break;
+	
+	        case "logia": case "logie":
+	        
+	            //Replace with log if in R2
+	            if(self::in(self::$r2_string,$max_suffix)){
+	                self::$buffer = str_replace($max_suffix,"log",
+					                self::$buffer);
+	                self::$step1_changes = true;
+	            }
+			    break;
+
+            case "uzione": case "uzioni": case "usione": case "usioni":
+	        
+	            //Replace with u if in R2
+	            if(self::in(self::$r2_string,$max_suffix)){
+	                self::$buffer = str_replace($max_suffix,"u",self::$buffer);
+		            self::$step1_changes = true;
+	            }
+                break;
+			
+            case "enza": case "enze":
+		
+                //Replace with ente if in R2
+	            if(self::in(self::$r2_string,$max_suffix)){
+	                self::$buffer = str_replace($max_suffix,"ente",
+					                self::$buffer);
+	                self::$step1_changes = true;
+	            }
+                break;
+
+            case "amento": case "amenti": case "imento": case "imenti":			
+    
+	            //Delete if in RV 
+	            if(self::in(self::$rv_string,$max_suffix)){
+	                self::$buffer = str_replace($max_suffix,"",self::$buffer);
+	                self::$step1_changes = true;
+                }
+			    break;
+
+            case "amente":
+	
+	            //Delete if in R1
+	            if(self::in(self::$r1_string,$max_suffix)){
+	                self::$buffer = str_replace($max_suffix,"",self::$buffer);
+	                self::$step1_changes = true;
+	            }
+	            //Check if preceded by iv, if yes, delete if in R2	
+                if(self::checkForSuffix(self::$buffer,"iv")){
+	                if(self::in(self::$r2_string,"iv")){
+	                    self::$buffer = str_replace("iv","",self::$buffer);
+	                    self::$step1_changes = true;
+			            if(self::checkForSuffix(self::$buffer,"at")){
+			                if(self::in(self::$r2_string,"at")){
+			                    self::$buffer = str_replace("at","",
+								                self::$buffer);
+		                        self::$step1_changes = true;
+				            }
+                        }				
+                    }			
+	            }
+			    /*Otherwise check if preceded by os,ic or abil, if yes,
+                 *delete if in r2
+                 */
+	            else{ 
+                    $further = Array("os","ic","abil");
+                    foreach($further as $suffix){
+					    if(self::checkForSuffix(self::$buffer,$suffix)){
+	                        if(self::in(self::$r2_string,$suffix)){
+				                self::$buffer = str_replace($suffix,"",
+							                    self::$buffer);
+				                self::$step1_changes = true;
+			                }    	
+                        }
+	                }
+			    }	
+                break;
+
+            case "ità":
+            
+                //Delete if in R2
+	            if(self::in(self::$r2_string,$max_suffix)){
+	                self::$buffer = str_replace($max_suffix,"",self::$buffer);
+	                self::$step1_changes = true;
+	            }	
+	            //If further preceded by abil,ic or iv, delete if in R2
+                $further = Array("abil","ic","iv");
+                foreach($further as $suffix){
+				    if(self::checkForSuffix(self::$buffer,$suffix)){
+	                    if(self::in(self::$r2_string,$suffix)){
+			                self::$buffer = str_replace($suffix,"",
+							                self::$buffer);
+		                    self::$step1_changes = true;
+		                }
+                    }					
+                }
+        
+            case "ivo": case "ivi": case "iva": case "ive":
+        
+                //Delete if in R2
+	            if(self::in($self::r2_string,$max_suffix)){
+		            self::$buffer = str_replace($max_suffix,"",self::$buffer);
+		            self::$step1_changes = true;
+				}	
+                //If preceded by at, delete if in R2
+			    if(self::checkForSuffix(self::$buffer,"at")){
+	                if(self::in(self::$r2_string,"at")){
+		                self::$buffer = str_replace("at","",self::$buffer);
+		                self::$step1_changes = true;
+					    if(self::checkForSuffix(self::$buffer,"ic")){
+	                        if(self::in(self::$r2_string,"ic")){
+			                    self::$buffer = str_replace("ic","",
+								                self::$buffer);
+			                    self::$step1_changes = true;
+		                    }
+				        }
+	                }
+                }			
+	    }		
+    }
+	
+	//Function step2: Verb suffixes
+	static function step2() 
+    {
+        $verb_suffixes = Array("ammo","ando","ano","are","arono","asse",
+		                       "assero","assi","assimo","ata","ate","ati",
+							   "ato","ava","avamo","avano","avate","avi","avo",
+							   "emmo","enda","ende","endi","endo","erà",
+							   "erai","eranno","ere","erebbe","erebbero",
+							   "erei","eremmo","eremo","ereste","eresti",
+							   "erete","erò","erono","essero","ete","eva",
+							   "evamo","evano","evate","evi","evo","Yamo",
+							   "iamo","immo","irà","irai","iranno","ire",
+							   "irebbe","irebbero","irei","iremmo","iremo",
+							   "ireste","iresti","irete","irò","irono","isca",
+							   "iscano","isce","isci","isco","iscono","issero",
+							   "ita","ite","iti","ito","ivamo","ivano","ivate",
+							   "ivi","ivo","ono","uta","ute","uti","uto","ar",
+							   "ir");
+    
+	    /*If no ending was removed in step1, find the longest suffix from the 
+	     *above suffixes and delete if in RV
+	     */
+        if(!self::$step1_changes){
+		    //Get R1,R2 and RV
+            self::getRegions();
+		    $max_suffix = self::maxSuffix(self::$buffer,$verb_suffixes);
+		    if(self::in(self::$rv_string,$max_suffix))
+		        self::$buffer = str_replace($max_suffix,"",self::$buffer);
+	    }
+    }
+	
+	/*Function step3a: Delete final a,e,i,o,à,è,ì,ò and a preceding i if
+	 *in RV
+	 */
+	function step3a()
+    {
+        $vowels = Array ("a","e","i","o","à","è","ì","ò");
+		
+		//Get R1,R2 and RV
+        self::getRegions();
+        
+		//If a character from the above is found in RV, delete it
+	    foreach($vowels as $character){
+		    $pos = self::checkForSuffix(self::$buffer,$character);
+            if($pos){
+		        if(self::in(self::$rv_string,$character)){
+		            self::$buffer = substr_replace(self::$buffer,"",$pos);
+			        //If preceded by i, delete if in RV
+					$pos = self::checkForSuffix(self::$buffer,"i");
+			        if($pos){
+			            if(self::in(self::$rv_string,"i"))
+				           self::$buffer = 
+						                substr_replace(self::$buffer,"",$pos);
+			        }
+                }				
+		    }	
+        }
+    }
+	
+	//Function step3b: Replace a final ch/gh by c/g if in RV
+	function step3b()
+    {
+        //Replace final ch/gh with c/g if in RV
+	    $patterns = Array("ch","gh");
+		
+		//Get R1,R2 and RV
+        self::getRegions();
+	    
+		foreach($patterns as $pattern){
+	        switch($pattern)
+		    {
+		        case "ch":
+			        if(self::checkForSuffix(self::$buffer,$pattern)){
+				        if(self::in(self::$rv_string,$pattern))
+				            self::$buffer = str_replace($pattern,"c",
+							                self::$buffer);
+				    }		
+			        break;
+
+                case "gh":
+			        if(self::checkForSuffix(self::$buffer,$pattern)){
+				        if(self::in(self::$rv_string,$pattern))
+				            self::$buffer = str_replace($pattern,"g",
+							                self::$buffer);
+				    }		
+			        break;			
+		    }
+	    }	
+	}
+	
+	//Function postlude: convert U and/or I back to lowercase
+	function postlude()
+    {   
+        //Convert U,I back into lower case
+        $pattern_array = Array("/U/","/I/");
+	    $replacement_array = Array("u","i");
+	    self::$buffer = preg_replace($pattern_array,$replacement_array,
+		                self::$buffer);     
+    }
+}
+?>
\ No newline at end of file
diff --git a/tests/ItStemmer_test.php b/tests/ItStemmer_test.php
new file mode 100644
index 0000000..3502414
--- /dev/null
+++ b/tests/ItStemmer_test.php
@@ -0,0 +1,128 @@
+﻿<?php
+/** 
+ *  SeekQuarry/Yioop --
+ *  Open Source Pure PHP Search Engine, Crawler, and Indexer
+ *
+ *  Copyright (C) 2009 - 2012  Chris Pollett chris@pollett.org
+ *
+ *  LICENSE:
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *  END LICENSE
+ *
+ * @author Chris Pollett chris@pollett.org
+ * @package seek_quarry
+ * @subpackage test
+ * @license http://www.gnu.org/licenses/ GPL3
+ * @link http://www.seekquarry.com/
+ * @copyright 2009 - 2012
+ * @filesource
+ */
+
+if(!defined('BASE_DIR')) {echo "BAD REQUEST"; exit();}
+
+/**
+ *  Load the Italian stemmer 
+ */
+require_once BASE_DIR."/locale/it/resources/tokenizer.php"; 
+/**
+ *  Load the crawlHash function
+ */
+require_once BASE_DIR.'/lib/unit_test.php'; 
+
+/*Used to test the Italian stemming algorithm correctly stems words 
+ *according to the rules given in snowball
+ * 
+ * @author Akshat Kukreti
+ */
+
+class ItStemmerTest extends UnitTest
+{
+    public function setUp()
+	{
+	    $this->test_objects['FILE1'] = new ItStemmer();
+	}
+	
+	public function tearDown()
+	{
+	}
+	
+	/*To test whether the stem funtion for the Italian stemming algorithm
+	 *stems words according to the rules of stemming. The function tests stem 
+     *by calling stem with the words in $test_words and compares the results 
+	 *with the stem words in $stem_words
+	 *
+	 *$test_words is an array containing a set of words in Italian provided in
+	 *the snowball web page
+	 *$stem_words is an array containing the stems for words in $test_words
+	 */
+	public function stemmerTestCase()
+	{   
+	    //Test word set from snowball 
+	    $test_words = Array("abbandonata","abbandonate","abbandonati",
+		                    "abbandonato","abbandonava","abbandonerà",
+                            "abbandoneranno","abbandonerò","abbandono",
+							"abbandonò","abbaruffato","abbassamento",
+                            "abbassando","abbassandola","abbassandole",
+                            "abbassar","abbassare","abbassarono","abbassarsi",
+                            "abbassassero","abbassato","abbassava","abbassi",
+                            "abbassò","abbastanza","abbatté","abbattendo",
+							"abbattere","abbattersi","abbattesse","abbatteva",
+                            "abbattevamo","abbattevano","abbattimento",
+							"abbattuta","abbattuti","abbattuto","abbellita",
+                            "abbenché","abbi","pronto","pronuncerà",
+							"pronuncia","pronunciamento","pronunciare",
+                            "pronunciarsi","pronunciata","pronunciate",
+                            "pronunciato","pronunzia","pronunziano",
+                            "pronunziare","pronunziarle","pronunziato",
+                            "pronunzio","pronunziò","propaga","propagamento",
+                            "propaganda","propagare","propagarla","propagarsi",
+                            "propagasse","propagata","propagazione",
+                            "propaghino","propalate","propende","propensi",
+                            "propensione","propini","propio","propizio",
+                            "propone","proponendo","proponendosi","proponenti", 
+                            "proponeva","proponevano","proponga");
+		
+	    //Stem word set from snowball for comparing results 
+        $stem_words = Array("abbandon","abbandon","abbandon","abbandon",
+                            "abbandon","abbandon","abbandon","abbandon",
+                            "abband","abbandon","abbaruff","abbass","abbass",
+                            "abbass","abbass","abbass","abbass","abbass",
+							"abbass","abbass","abbass","abbass","abbass",
+							"abbass","abbast","abbatt","abbatt","abbatt",
+							"abbatt","abbattess","abbatt","abbatt","abbatt",
+							"abbatt","abbatt","abbatt","abbatt","abbell",
+							"abbenc","abbi","pront","pronunc","pronunc",
+							"pronunc","pronunc","pronunc","pronunc","pronunc",
+                            "pronunc","pronunz","pronunz","pronunz","pronunz",
+                            "pronunz","pronunz","pronunz","propag","propag",
+                            "propagand","propag","propag","propag","propag",
+                            "propag","propag","propaghin","propal","prop",
+							"propens","propension","propin","prop","propiz",
+                            "propon","propon","propon","proponent","propon",
+                            "propon","propong");		
+		
+		/*check if function stem correctly stems the words in $test_words by
+		 *comparing results with stem words in $stem_words
+		 */
+		for($i = 0;$i < sizeof($test_words);$i++){
+	        $this->assertEqual(
+                $this->test_objects['FILE1']->stem($test_words[$i]),
+				    $stem_words[$i],"function stem correctly stems 
+					$test_words[$i] to $stem_words[$i]");
+		}		
+    }
+}
+?>
\ No newline at end of file
-- 
1.7.9.msysgit.0

