#!/usr/bin/env perl

#
# Precision-oriented evaluation program for NTCIR-5 Passage Retrieval Task
#

$| = 1;

sub read_trec ($) {
    my($file) = @_;
    my($topic, $x, $pasid, $rank, $score, $sysid);

    %pas_rank = ();
    open(IN, $file) || die "$file: $!";
    while (<IN>) {
	chomp;
	next if (/^</);
	($topic, $x, $pasid, $rank, $score, $sysid) = split(/\t/, $_);
	$topic =~ s/^P//;
	$pas_rank{$topic, $pasid} = $rank;
    }
    close(IN);
}

sub proc_one_pas ($$) {
    my($topic, $pas) = @_;
    my(@and_pas, @or_pas, $and_pas, $or_pas, $max_rank, $min_rank);

    @and_pas = split(/\*/, $pas);
    $max_rank = -1;
    foreach $and_pas (@and_pas) {
	$and_pas =~ s/\(//;
	$and_pas =~ s/\)//;
	@or_pas = split(/\+/, $and_pas);
	$min_rank = -1;
	foreach $or_pas (@or_pas) {
	    $or_pas =~ s/^<PNUM>//;
	    $or_pas =~ s/<\/PNUM>$//;

	    if (($min_rank < 0) ||
		($pas_rank{$topic, $or_pas} < $min_rank)) {

		$min_rank = $pas_rank{$topic, $or_pas};
	    }
	}

	if ($min_rank > $max_rank) {
	    $max_rank = $min_rank;
	}
    }

    return $max_rank;
}

sub read_rel ($$) {
    my($file, $level) = @_;
    my($topic, $rel, $docid, $pas);

    %min_rank = ();
    open(IN, $file) || die "$file: $!";
    while (<IN>) {
	chomp;
	($topic, $rel, $docid, $pas) = split(/\t/, $_);

	if (($level =~ /^A$/i) && ($rel !~ /^A$/)) {
	    next;
	}

	$topic =~ s/^P//;
	$rank = &proc_one_pas($topic, $pas);
	if (!defined($min_rank{$topic}) || ($rank < $min_rank{$topic})) {
	    $min_rank{$topic} = $rank;
	}
    }
    close(IN);
}

sub out_result {
    my($avg_rank, $z);

    $z = 0;
    foreach (sort {$a <=> $b} keys %min_rank) {
	$avg_rank += $min_rank{$_};
	print "$_\t$min_rank{$_}\n";
	$z++;
    }
    
    $avg_rank /= $z;

    printf "Avg.\t%.2f\n", $avg_rank;
}

sub main {
    if (@ARGV != 3) {
	print STDERR "Usage: $0 <rel> <trec> <level (a/b)>\n";
	exit;
    }

    ($rel, $trec, $level) = @ARGV;

    %pas_rank = ();
    &read_trec($trec);
    %min_rank = ();
    &read_rel($rel, $level);

    &out_result;
}

&main;
