<?

// $Id: porter_stemming.php,v 1.1 2002/08/26 01:13:41 sella Exp $
//
// Created By: Joe Stump
// Created On: 2000-12-14
// Notes: This is the infamous "Porter Stemming Algorithm" - lots
// of serach engines use something similar to relate words. An example
// would be to turn "running" into "run" but "kissing" into "kiss".
//
// The "Porter Stemming Algorithm" can be found at the following URL:
// http://open.muscat.com/developer/docs/porterstem.html
//
// Returns: string PorterStem(string word)

function PorterStem($word) {
	/**
	 Copyright 2000 Joe Stump <joestump98@yahoo.com>
	 http://www.miester.org

	 Porter Stemming Algorithm for PHP.
	 Release 1.0.0
	 http://www.miester.net/software/

	 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 2 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, write to the Free Software
	 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
	 INSTRUCTIONS FOR USE:
	**/

	$vowels = array('a', 'e', 'i', 'o', 'u', 'y');
	$o = array('w', 'x', 'y');

	$test_m = eregi_replace('^[a-z]', '', $word);
	$test_m = eregi_replace('[a-z]$', '', $test_m); 
	for ($i = 0 ; $i < strlen($test_m) ; ++$i) {
		if (eregi('[b-df-hj-np-tw-z]', $test_m[$i]) && eregi('[aeiou]', $test_m[($i - 1)])) {
			++$total;
		}
	}

	if ($total) {
		$m = $total;
	} else {
		$m = 0;
	}

	// Step 1a
	$replaces = array('sses$' => 'ss', 'ies$' => 'i', 'ss$' => 'ss', 's$' => '');

	while (list($search, $replace) = each($replaces)) {
		$word = eregi_replace($search, $replace, $word);
	}

	// Step 1b
	if ($m > 0) {
		$word = eregi_replace('eed$', 'ee', $word);
	}

	$do_more = 0;
	if (eregi('[aeiou]',eregi_replace('ed$', '', $word))) {
		$word = eregi_replace('ed$', '', $word);
		$do_more = 1;
	}
 
	if (eregi('[aeiou]',eregi_replace('ing$', '', $word))) {
		$word = eregi_replace('ing$', '', $word);
		$do_more = 1;
	}

	if ($do_more) {
		$more_replace = array('at$' => 'ate', 'bl$' => 'ble', 'iz$' => 'ize');
		while (list($s, $r) = each($more_replace)) {
			$word = eregi_replace($s, $r, $word);
		}

		$length = strlen($word);
		$last_letter = substr($word, ($length - 1), $length);
		$next_last_letter = substr($word, (strlen($word) - 2), -1);
		if (($last_letter == $next_last_letter) && !dgs_in_array($last_letter,array('l', 's', 'z'))) {
			$word = substr($word, 0, (strlen($word) - 1));
		}

		if ($m == 1 && eregi('[b-df-hj-np-tv-z][aeiou][b-df-hj-np-tv-z]$', $word) && !dgs_in_array($last_letter, $o)) {
			$word .= 'e';
		}
	}


	// Step 1c
	if (eregi('[aeiou]', $word) && eregi('y$', $word) && $m == 1 && !eregi('ly$', $word)) {
		$word = eregi_replace('y$', 'i', $word);
	}

	// Step 2
	$replaces = array('ational$' => 'ate', 'tional$' => 'tion', 'enci$' => 'ence', 'anci$' => 'ance', 'izer$' => 'ize', 'abli$' => 'able', 'alli$' => 'al', 'entli$' => 'ent', 'eli$' => 'e', 'ousli$' => 'ous', 'ization$' => 'ize', 'ation$' => 'ate', 'ator$' => 'ate', 'alism$' => 'al', 'iveness$' => 'ive', 'fulness$' => 'ful', 'ousness$' => 'ous', 'aliti$' => 'al', 'iviti$' => 'ive', 'biliti$' => 'ble');

	while (list($search, $replace) = each($replaces)) {
		if ($m > 0) {
			$word = eregi_replace($search, $replace, $word);
		}
	}

	// Step 3
	$replaces = array('icate$' => 'ic', 'ative$' => '', 'alize$' => 'al', 'iciti$' => 'ic', 'ical$' => 'ic', 'ful$' => '', 'ness$' => '');

	while (list($search, $replace) = each($replaces)) {
		if ($m > 0) {
			$word = eregi_replace($search, $replace, $word);
		}
	}

	// Step 4a
	$replaces = array('al$' => '', 'ance$' => '', 'ence$' => '', 'er$' => '', 'ic$' => '', 'able$' => '', 'ible$' => '', 'ant$' => '', 'ement$' => '', 'ment$' => '', 'ent$' => '', 'tion$' => 't', 'sion$' => 's', 'ou$' => '', 'ism$' => '', 'ate$' => '', 'iti$' => '', 'ous$' => '', 'ive$' => '', 'ize$' => '');

	while (list($search, $replace) = each($replaces)) {
		if ($m > 1) {
			$word = eregi_replace($search, $replace, $word);
		}
	}

	// Step 5a
	if ($m > 1 && ereg('e$', $word)) {
		$word = eregi_replace('e$', '', $word);
	}

	if ($m == 1 && !(eregi('[b-df-hj-np-tv-z][aeiou][b-df-hj-np-tv-z]$', $word) && !dgs_in_array($last_letter, $o))) {
		$word = eregi_replace('e$', '', $word);
	}

	// Step 5b
	if ($m > 1) {
		$word = eregi_replace('ll$', 'l', $word); 
	}

	// This is NOT part of the original Porter Stemming Algorithm
	if ($m > 0) {
		$word = eregi_replace('ly$', '', $word);
	}
	return $word;
}

/*
** Local Variables:
** c-basic-offset: 3
** tab-width: 3
** End:
** vim600: fdm=marker
** vim: noet ts=3 sw=3
*/

?>
