#!/usr/bin/perl
#
#  Copyright (c) 1997-2004
#  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
#  http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de
#
#  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, or (at your option) any
#  later version: http://www.gnu.org/licenses/gpl.txt.
#
#  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.
#-----------------------------------------------------------------------------
#  $Project: polymake $$Id: porta2poly,v 1.2 2004/06/22 16:23:11 gawrilow Exp $

#  @file porta2poly
#
#  Convert a polyhedron file in porta input format (.poi or .ieq)
#  to polymake description and print it to stdout.
#
#  @synopsis porta2poly IN_FILE.{poi,ieq} >OUT_FILE.poly
#
#  @index utilities

use strict;

die "$0 IN_FILE.{poi,ieq} >OUT_FILE.poly"
if @ARGV != 1  or  $ARGV[0] !~ /\.(poi|ieq)$/;
my $primal= $1 eq "poi";

open IN, "$ARGV[0]" or die "$0: can't read $ARGV[0]: $!\n";

my $dim;
while (<IN>) {
   if (/DIM\s*=\s*(\d+)/) {
      $dim=$1;
      print "AMBIENT_DIM\n$dim\n\n";
      last;
   }
}

if ($primal) {
   my ($leading);

 IN1:
   while (<IN>) {
      if (/CON([VE])_SECTION/) {
	 print "POINTS\n" unless defined $leading;
	 $leading= $1 eq "V" ? "1" : "0";

	 while (<IN>) {
	    next unless /\S/;
	    if (/\d/) {
	       s/^\s*(?:\(.*?\))?//;
	       print "$leading $_";
	    } else {
	       redo IN1;
	    }
	 }
      } elsif (/END/) {
	 last;
      } elsif (/\S/) {
	 die "$0: unrecognized line: $_\n";
      }
   }
   print "\n" if defined $leading;

} else {

   my (@inequalities, @equations);

 IN2:
   while (<IN>) {
      if (/VALID/) {

	 while (<IN>) {
	    if (/\S/) {
	       print "VALID_POINT\n1 $_\n";
	       last;
	    }
	 }

      } elsif (/INEQUALITIES_SECTION/) {

	 while (<IN>) {
	    next unless /\S/;
	    last unless /[<=>]=/;
	    my ($lhs, $to, $invert, $rhs)= ($`, (substr($&,0,1) eq "=" ? \@equations : \@inequalities),
					    (substr($&,0,1) eq ">" ? "-" : ""), $');
	    $lhs =~ s/^\s*(?:\(.*?\))?//;
	    $rhs =~ s/\s//g;
	    if ($invert ne "") {
	       $rhs =~ s/^-//  or  $rhs =~ s/^\+?/-/;
	    }
	    my $n=1;
	    my @vector=($rhs);
	    while ($lhs =~ /(?:\+|(-))?\s*([^-+x\s]*)\s*x(\d+)/g) {
	       my ($sign, $coeff, $index)=($1,$2,$3);
	       if ($n<$index) {
		  push @vector, (0)x($index-$n);
		  $n=$index;
	       }
	       $coeff =~ s/\s//g;
	       if (length($coeff)) {
		  if ($sign eq $invert) {
		     $coeff =~ s/^-//  or  $coeff =~ s/^\+?/-/;
		  }
	       } else {
		  $coeff= $sign eq $invert ? -1 : 1;
	       }
	       push @vector, $coeff;
	       ++$n;
	    }
	    push @vector, (0)x($dim-$n+1);
	    push @$to, "@vector\n";
	 }

	 redo;

      } elsif (/(LOWER|UPPER)_BOUNDS/) {

	 my $coeff= substr($1,0,1) eq "L" ? 1 : -1;

	 while (<IN>) {
	    if (/\S/) {
	       my $index=0;

	       foreach my $b (split) {
		  my $bound=$b;
		  if ($coeff>0) {
		     $bound =~ s/^-//  or  $bound =~ s/^\+?/-/;
		  }
		  my @vector=($bound, (0)x$index, $coeff, (0)x($dim-$index-1));
		  push @inequalities, "@vector\n";
		  ++$index;
	       }
	       die "BOUNDS dimension mismatch\n" if $index != $dim;
	       last;
	    }
	 }

      } elsif (/ELIMINATION_ORDER/) {

	 while (<IN>) {
	    last if /\S/;
	 }

      } elsif (/END/) {
	 last;
      } elsif (/\S/) {
	 die "$0: unrecognized line: $_\n";
      }
   }

   if (@inequalities) {
      print "INEQUALITIES\n", @inequalities, "\n";
   }
   if (@equations) {
      print "EQUATIONS\n", @equations, "\n";
   }
}

print "\n_application polytope\n";


# Local Variables:
# mode: perl
# c-basic-offset:3
# End:
