#!/usr/local/bin/perl -w
#
#############################################################################
#
#       PROGRAM NAME-  socs.pl (A Component of NSP Package)
#	This program finds the second order co-occurrences of a given target 
#	word using bigram output created by the programs count.pl or 
#	statistic.pl of the NSP
#
#############################################################################
#                       ---------------------
#                       COPYRIGHT INFORMATION
#                       ---------------------

# Copyright (c) 2002,
# Amruta Purandare, University of Minnesota, Duluth
# pura0010@d.umn.edu
# Ted Pedersen, University of Minnesota, Duluth
# tpederse@umn.edu
#
# 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.
#
###############################################################################

#                               THE CODE STARTS HERE

###############################################################################

#                           ================================
#                            COMMAND LINE OPTIONS AND USAGE
#                           ================================

# show minimal usage message if no arguments
if($#ARGV<0)
{
        &showminimal();
        exit;
}

# command line options
use Getopt::Long;
GetOptions ("help","version");
# show help option
if(defined $opt_help)
{
        $opt_help=1;
        &showhelp();
        exit;
}

# show version information
if(defined $opt_version)
{
        $opt_version=1;
        &showversion();
        exit;
}

#############################################################################

#                       ================================
#                          INITIALIZATION AND INPUT
#                       ================================

#$0 contains the program name along with
#a complete path. Extract just the program
#name and use in error messages
$0=~s/.*\/(.+)/$1/;

if(!defined $ARGV[0])
{
        print STDERR "ERROR($0):
        Please specify the SOURCE file name...\n";
        exit;
}
#accept the input file name
$infile=$ARGV[0];
#check if exists
if(!-e $infile)
{
        print STDERR "ERROR($0):
        Source file <$infile> doesn't exist...\n";
        exit;
}
#open if exists
open(IN,"$infile") || die "Error($0):
        Error(code=$!) in opening <$infile> file.\n";

#check if the target word exists
if(!defined $ARGV[1])
{
	print STDERR "ERROR($0):
	Please specify the target word whose second order co-occurrences are to be found.\n"; 
	exit;
}

#accept the target word 
$word=$ARGV[1];

##############################################################################

$line_num=0;
#creating a coc_store data structure for storing all bigram strings from SOURCE
#so that co-occurrences can be found looking at this data structure
while($line=<IN>)
{
	$line_num++;
        # trimming extra spaces
        chomp $line;
        $line=~s/\s+$//g;
        $line=~s/^\s+//g;
        $line=~s/\s+/ /g;
	# handling blank lines
        if($line=~/^\s*$/)
        {
                next;
        }
	#store the bigram strings before the last <> 
	if($line=~/<>/)
	{
		#checking if the SOURCE is a valid NSP output for Bigrams
		$check_bigram=$line;
		$cnt=0;
		#count how many times <> occurs
		while($check_bigram=~/<>/)
		{
			$cnt++;
			$check_bigram=$';
		}
		#should be 2 for bigrams
		if($cnt!=2)
		{
			print STDERR "ERROR($0):
	SOURCE file <$infile> is not a valid Bigram output of count.pl or 
	statistic.pl of NSP Package at line <$line_num>.\n";
			exit;
		}
		#part before the last <>
		$line=~s/<>[\d\s\.]*$//;
		#coc_store can referred to know the word co-occurring
		push @coc_store,$line;
	}
}

#'words' contains the words whose co-occurrences are to be found.
#initially it contains the target word
push @words,$word;
foreach (1..2)
{
	#contains co-occurrences of the current order
        @cocs_this=();
	foreach $lookfor_word (@words)
	{
		if($lookfor_word ne "")
		{
			#the function will return the words co-occurring 
			#with the word passed as a parameter 
			@from_cocs=&cocs($lookfor_word);
			if($#from_cocs<0)
			{
				print "ERROR($0):
	Word <$lookfor_word> is not found in the SOURCE file <$infile>.\n";
				exit;
			}
			push @cocs_this,@from_cocs;
		}
	}
	#find unique co-occurrences
	foreach (@cocs_this)
	{
       		$cocs_this{$_}=1;
	}
	# find co-occurrences of 'words' in the next iteration 
	@words=();
	foreach (keys %cocs_this)
        {
                push @words,$_;
                delete $cocs_this{$_};
        }
}
#print the co-occurrences
foreach (@words)
{
	if($_ ne $word)
	{
		print "$_<>\n";
		$got=1;
	}
}
if(!defined $got)
{
	print STDERR "No 2nd order co-occurrences found.\n";
}
##############################################################################

#                      ==========================
#                          SUBROUTINE SECTION
#                      ==========================

#-----------------------------------------------------------------------------

#----------------
#Subroutine cocs
#----------------
#returns all words co-occurring with a given word
sub cocs
{
	my $word=$_[0];	
	#string from the coc_store
	my $coc_string="";	
	#array of unique co-occurrences of the word
	my @return_cocs=();
	#to find the unique co-occurrences of the word
	my %return_hash;
	foreach $coc_string (@coc_store)
	{
		#find those bigrams which contain the target word 
		#and find the other word that co-occurs this word
		if($coc_string=~/^$word<>(.*)$/ || $coc_string=~/^(.*)<>$word$/)
		{
			$return_hash{$1}=1;
		}
	}
	#form an array of these co-occurrences
	foreach (keys %return_hash)
	{
		push @return_cocs,$_;
	}
	return @return_cocs;
}

#-----------------------------------------------------------------------------
#show minimal usage message
sub showminimal()
{
        print "Usage: socs.pl [OPTIONS] SOURCE WORD";
        print "\nTYPE socs.pl --help for help\n";
}

#-----------------------------------------------------------------------------
#show help
sub showhelp()
{
	print "Usage:  socs.pl [OPTIONS] SOURCE WORD 
Finds 2nd order co-occurrences of a given WORD using Bigrams from SOURCE.

SOURCE 
	A list of Bigrams formatted like the output(extended or normal) of 
	count.pl or statistic.pl of the NSP Package. If SOURCE is not 
	automatically created by NSP, please consult the README of NSP for a 
	description of this format.

WORD
	Specify the WORD whose 2nd order co-occurrences are to be found.

OPTIONS:
--help
        To display this message.

--version
        To display the version information.\n";
}

#------------------------------------------------------------------------------
#version information
sub showversion()
{
        print "socs.pl         -       version 0.01\n";
        print "A component of the NSP, version 0.53\n"; 
        print "Copyright (C) 2002-2003, Ted Pedersen and Amruta Purandare\n";
        print "Date of Last Update:     01/13/2003\n";
}

#############################################################################

