#!/usr/bin/perl -w
use strict;

use WordNet::SenseRelate::AllWords;
use WordNet::QueryData;
use WordNet::Tools;

my $verbose = 0;

my $filepath = "h:\\itaproj\\code\\meetme-conf-rec-8000-1234462646.22.txt";
my $csvfileout = "h:\\itaproj\\code\\meetme-conf-rec-8000-1234462646.22_wsd.csv";

open F1, $filepath;
open F2, ">$csvfileout";

my $qd = WordNet::QueryData->new;
my $wntools = WordNet::Tools->new($qd);

my $wsd = WordNet::SenseRelate::AllWords->new (wordnet => $qd,
                                                wntools => $wntools,
                                                measure => 'WordNet::Similarity::lesk',
                                                config => "h:\\itaproj\\code\\conf.txt");

print F2 "Word,Score,SensesSD\n";

while(my $tempText = <F1>)
{
    $tempText =~ m/p\d:\s*(.*)/i;
    my $sentence = $1;
    if($sentence)
    {
        my %scores = ();
        print "Processing sentence : $sentence\n";
        print F2 "$sentence\n";
        
        my @context = tokenizeSentence($sentence);
        my @results = $wsd->disambiguate (window => 4, context => [@context], scores => \%scores);
        print F2 join(',',@results);
        print F2 "\n";
        
        foreach my $key (keys %scores)
        {
            my $sensessd = getSensesSD($key, $qd);
            my $score = $scores{$key};
            print F2 "$key,$score,$sensessd\n";
        }
    }
}

close(F2);
close(F1);

#Converts the given sentence to a data structure used for internal purposes.
#Input is the sentence.
#Output is an array of words.
sub tokenizeSentence
{
    print "Inside tokenizeSentence ...\n" if($verbose);
    my $sentence = shift;
    my @words = split(/[^A-Za-z0-9]/, $sentence);
    return @words;
}

#Calculate the standard deviation for a list of numbers.
sub getSD
{
  my $ar = shift;
  my $elements = scalar @$ar;
  my $sum = 0;
  my $sumsq = 0;

  foreach (@$ar)
  {
    $sum += $_;
    $sumsq += ($_ **2);
  }
  
  return sqrt( $sumsq/$elements - (($sum/$elements) ** 2));
}

#Calculate the standard deviation for frequencies of different senses of a given word.
#Inputs are:
#The word.
#WordNet::QueryData object to work on.
#Output is the required standard deviation.
sub getSensesSD
{
    print "Inside getSensesSD ...\n" if($verbose);
    
    my $word = shift;
    my $wordnet = shift;
    my @sensefreqs;
    
    my @pos = $wordnet->querySense($word);
    foreach my $tempPos (@pos)
    {
        print "Processing for POS ==> $tempPos\n" if ($verbose);
        
        my @senses = $wordnet->querySense($tempPos);
        foreach my $tempSense (@senses)
        {
            my $tempFreq = 1 + $wordnet->frequency($tempSense);
            push(@sensefreqs, $tempFreq);
            
            print "Sense ==> $tempSense ... Freq ==> $tempFreq\n" if ($verbose);
        }
    }
    my $sdfreqs = 0;
    $sdfreqs = getSD(\@sensefreqs) if(@sensefreqs);
    return $sdfreqs;
}