#!/usr/bin/perl
# Copyright (C) 1997 Ullrich Hustadt
#                    Max-Planck-Institut fuer Informatik
#                    Im Stadtwald
#                    66123 Saarbruecken, Germany
#
# prepare-flotter 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 1, or (at your option)
# any later version.
#
# prepare-flotter 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.

$file = shift(@ARGV);
#print(STDOUT "Diamonds shared on $file");
$tmp_file = "/tmp/flotter.$$";
&slurp_input($file);
$add = "";
$number = 0;
if (/ndr1_0/) {
#  print(STDOUT " [Functional translation]\n");
#  &replV1();
} elsif (/ndr1\(/) {
#  print(STDOUT " [Semi-functional translation]\n");
  &replV2();
};
$add = "";
if ($number >0) {
  $number--;
  foreach $index (0..$number) {
    $add .= ", (hskp$index, 0)";
  };
  s/(predicates\[[^\]]+)\]/$1$add\]/;
};
open(OUT,">$tmp_file");
select(OUT);
print("$_");
close(OUT);
system("mv $tmp_file $file");

sub slurp_input {
  local($file) = @_;
  open(IN,$file);
  $input = "";
  while (<IN>) {
    $input .= $_;
  };
  close(IN);
  $_ = $input;
}

sub replV1 {
  $changed = 1;
  while ((/and\(ndr1_0,and/) &&
         ($changed)) {
    $changed = 0;
    if (/(and\(ndr1_0,and\([^\,]+\,[^\,]+\,not[^\)]+\)\)\)\))/) {
      $form = $1;
      $dia =  $form;
      print(STDOUT "0 dia: $dia");
      $dia =~ s/\(/\\\(/g;
      $dia =~ s/\)/\\\)/g;
      $dia =~ s/a\d+/a\\d\+/g;
      print(STDOUT "1 dia: $dia");
      if ($dia =~ /(e[^b]+ba)/) {
	$index = $1;
	print(STDOUT "Found skolem constant $index\n");
	if ($lt{$index}) {
	  $predNum = $lt{$index}
	} else {
	  $predNum = $number;
	  $lt{$index} = $number;
	  $add .= "or(not(hskp$number),$form),\n";
	  $number++;
	};
      };
      s/$dia/hskp$predNum/g;
      $changed=1;
    } elsif (/(and\(ndr1_0,and\([^\,]+\,[^\,]+,[^\)]+\)\)\))/) {
      $form = $1;
      $dia =  $form;
      $dia =~ s/\(/\\\(/g;
      $dia =~ s/\)/\\\)/g;
      $dia =~ s/a\d+/a\\d\+/g;
      if ($dia =~ /(e[^b]+ba)/) {
	$index = $1;
	print(STDOUT "Found skolem constant $index\n");
	if ($lt{$index}) {
	  $predNum = $lt{$index}
	} else {
	  $predNum = $number;
	  $lt{$index} = $number;
	  $add .= "or(not(hskp$number),$form),\n";
	  $number++;
	};
      };
      s/$dia/hskp$predNum/g;
      $changed=1;
    };
  };
  s/and\(/and\($add/;
}

sub replV2 {
  s/Z/X0/g;
  s/\[Z\]/\[X0\]/g;
  $changed = 1;
  while ((/and\(ndr1\(\w+\),exists\(\[\w+\],and\(/) &&
         ($changed)) {
    $changed = 0;
    if (/(and\(ndr1\(\w+\),exists\(\[\w+\],and\([^\,]+\,[^\,]+\,[^\,]+\,[^\,]+\,not[^\)]+\)\)\)\)\)\))/) {
      $dia = $1;
      $dia =~ s/\(/\\\(/g;
      $dia =~ s/\)/\\\)/g;
      $dia =~ s/\[/\\\[/g;
      $dia =~ s/\]/\\\]/g;
      $dia =~ s/X\d+/X\\d\+/g;
#      print(STDOUT "Sharing - $dia\n");
      s/$dia/hskp$number/g;
      $add .= "or(not(hskp$number),$1),\n";
      $number++;
    } elsif (/(and\(ndr1\(\w+\),exists\(\[\w+\],and\([^\,]+\,[^\,]+\,[^\,]+\,[^\,]+\,[^\)]+\)\)\)\)\))/) {
      $dia = $1;
#      print(STDOUT "Sharing + $dia\n");
      $dia =~ s/\(/\\\(/g;
      $dia =~ s/\)/\\\)/g;
      $dia =~ s/\[/\\\[/g;
      $dia =~ s/\]/\\\]/g;
      $dia =~ s/X\d+/X\\d\+/g;
      s/$dia/hskp$number/g;
      $add .= "or(not(hskp$number),$1),\n";
      $changed=1;
      $number++;
    };
  };
  s/exists\(\[W\]\,and\(/exists\(\[W\]\,and\($add/;
}

sub replV3 {
  while (/and\(ndr1_0,/) {
    if (/(and\(ndr1_0,and\([^\,]+\,[^\,]+,not[^\)]+\)\)\)\))/) {
      $dia = $1;
      $out = $1;
      $dia =~ s/\(/\\\(/g;
      $dia =~ s/\)/\\\)/g;
      $dia =~ s/a\d+/a\\d\+/g;
      $out =~ s/a\d+/X/g;
      $out =~ s/ndr/NDR/g;
      $out =  "exists([X],$out)";
      s/$dia/$out/g;
    } elsif (/(and\(ndr1_0,and\([^\,]+\,[^\,]+,[^\)]+\)\)\))/) {
      $dia = $1;
      $out = $1;
      $dia =~ s/\(/\\\(/g;
      $dia =~ s/\)/\\\)/g;
      $dia =~ s/a\d+/a\\d\+/g;
      $out =~ s/a\d+/X/g;
      $out =~ s/ndr/NDR/g;
      $out =  "exists([X],$out)";
      s/$dia/$out/g;
    };
    s/NDR/ndr/g;
  };
}
