#!/usr/bin/env perl

use strict;

my %xsucc = ();
my %ysucc = ();
my %xvalue = ();
my %yvalue = ();
my %bottle = ();
my %bottleof = ();
my %filled = ();

my $debug = 0;

#############################################################################
# subs

######################
# 

sub invalid_exit {
  print "WARN\n";
  exit 1;
}

######################
# 

sub incorrect_exit {
  print "FAIL\n";
  exit 0;
}

######################
# 

sub correct_exit {
  print "OK\n";
  exit 0;
}

######################
# 

sub unverified_exit {
  print "DONTKNOW\n";
  exit 2;
}

######################
# 

sub parse_bottle_filling_instance_and_solution {
  my $IF = shift;
  my ($xsucc,$ysucc,$xvalue,$yvalue,$bottle,$filled) = @_;

  while(<$IF>) {
    chomp;
    my @facts = split(/\.\s*/);
    foreach my $f (@facts) {
      if( $f =~ /^xsucc\(([a-z0-9][A-Za-z0-9]*),([a-z0-9][A-Za-z0-9]*)\)$/ ) {
        $$xsucc{$1}=$2;
      } elsif ( $f =~ /^ysucc\(([a-z0-9][A-Za-z0-9]*),([a-z0-9][A-Za-z0-9]*)\)$/) {
        $$ysucc{$1}=$2;
      } elsif ( $f =~ /^xvalue\(([a-z0-9][A-Za-z0-9]*),([0-9]+)\)$/) {
        $$xvalue{$1}=$2;
      } elsif ( $f =~ /^yvalue\(([a-z0-9][A-Za-z0-9]*),([0-9]+)\)$/) {
        $$yvalue{$1}=$2;
      } elsif ( $f =~ /^bottle\(([a-z0-9][A-Za-z0-9]*),([a-z0-9][A-Za-z0-9]*),([a-z0-9][A-Za-z0-9]*)\)$/ ) {
        if ( ! $bottle{$1}) {
          $bottle{$1} = [[$2,$3]];
        } else {
          push(@{$bottle{$1}},[$2,$3]);
        }
        if ( exists $bottleof{$2,$3} ) {
            print STDERR "field in multiple bottle declaration" if $debug;
            return 0;
        }
        $bottleof{$2,$3}=$1;
      } elsif ( $f =~ /^filled\(([a-z0-9][A-Za-z0-9]*),([a-z0-9][A-Za-z0-9]*)\)$/) {
        $$filled{$1,$2}=1;
      } else {
        print STDERR "parse error: $f\n" if $debug;
        return 0;
      }
    }
  }
  return 1;
}


######################
# 

sub check_filled_integrity {
  my ($bottleof,$filled) = @_;

  foreach my $f (keys(%$filled)) {
    print "Filled integrity: $f: $$filled{$f}\n" if $debug;
    return 0 if ! exists $$bottleof{$f};
  }
  return 1;
}

sub check_filled_gravity {
  my ($bottle,$filled,$ysucc) = @_;

  foreach my $b (keys(%$bottle)) {
    foreach my $f ( @{$bottle{$b}} ) {
      if( $$filled{$f} ) {
        foreach my $g ( @{$bottle{$b}} ) {
          if( ! $$filled{$g} 
              && ( $$f[1] == $$g[1] || $ysucc{$$f[1],$$g[1]} == 1 ) ) {
            print "Filled gravity: $f filled, $g unfilled\n" if $debug;
            return 0;
          }
        }
      }
    }
  }
  return 1;
}

sub check_filled_x_count {
  my ($filled,$xvalue) = @_;

  foreach my $y (keys(%$xvalue)) {
    my $count = 0;
    foreach my $f (keys(%$filled)) {
        my ($fx,$fy) = (split $;, $f)[0,1];
        $count++ if $fy == $y;
    }
    return 0 if $count != $$xvalue{$y};
  }
  return 1;
}

sub check_filled_y_count {
  my ($filled,$yvalue) = @_;

  foreach my $x (keys(%$yvalue)) {
    my $count = 0;
    foreach my $f (keys(%$filled)) {
        my ($fx,$fy) = (split $;, $f)[0,1];
        $count++ if $fx == $x;
    }
    return 0 if $count != $$yvalue{$x};
  }
  return 1;
}

#############################################################################
# "main"

if ( @ARGV != 0 )
{
	die "Usage: $0\n";
}


# Parse instance file and solver output.
parse_bottle_filling_instance_and_solution(\*STDIN,\%xsucc,\%ysucc,\%xvalue,\%yvalue,\%bottle,\%filled) || invalid_exit;



# Sanity check: Are all filled locations in a bottle?
check_filled_integrity(\%bottleof,\%filled) || incorrect_exit;

# Gravity check: Do the filled locations respect gravity?
check_filled_gravity(\%bottle,\%filled,\%ysucc)  || incorrect_exit;

# X count check: Do row counts match?
check_filled_x_count(\%filled,\%xvalue)  || incorrect_exit;

# Y count check: Do column counts match?
check_filled_y_count(\%filled,\%yvalue)  || incorrect_exit;

correct_exit;

