#! /usr/bin/perl -w
# This awful single-use script expands out a description of a
# two-state cellular automaton in Golly table format (such as Conway's
# Life) into an equivalent rule table that collapses the 32 "Bedstead"
# states (16 on, 16 off) into the 2 automaton states while applying
# the same rule.
# It's slightly complicated because it's designed to work with
# the output of Golly make-ruletable.cpp, which is somewhat optimised
# using variables, but this script makes no attempt to optimise its
# output. It uses poorly-named variables to do a lot of its work.

# This file is part of Bedbugs.
# Copyright (C) 2014 Jacob Nevins.
#
# 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 of the License, or
# (at your option) any later version.
#
# 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.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

my %vars = ();
my $done_vars = 0;

while(<>) {
    if (m/^#/) {
        print $_;
    } elsif (m/^(n_states|neighborhood|symmetries):/) {
        print $_;
    } elsif (m/^var /) {
        die "Complicated variable" unless m/^var (.)=\{0,1\}$/;
        $vars{$1} = 1;
    } else {
        # Assume this is a table rule.
        chomp;
        my @cells = split /,/;
        my %myvars = ();
        # Only supports 8-neighbour automata
        die "Unexpected number of comma-separated items" unless @cells == 10;
        my @dirs = qw/c n ne e se s sw w nw/;
        if (!$done_vars) {
            # Variables to match 32 states rather than 2
            # Numbering of states highly tied to bedbugs.c output
            # Crap naming scheme: z=off, a=on, q=either
            print "var zz={0," . join(",", 2..17) . "}\n";
            print "var aa={" . join(",", 18..33) . "}\n";
            foreach my $d (@dirs) {
                print "var z$d={zz}\n";
                print "var a$d={aa}\n";
                print "var q$d={z$d,a$d}\n";
            }
            $done_vars = 1;
        }
        my $i = 0;
        while (my $dir = pop @dirs) {
            # Assume each variable in the input is only referenced once
            # per table row
            die "Duplicate var" if exists($myvars{$cells[$i]});
            if (exists($vars{$cells[$i]})) {
                $myvars{$cells[$i]} = 1;
                $cells[$i] = "q".$dir;
            } elsif ($cells[$i] eq "0") {
                $cells[$i] = "z".$dir;
            } elsif ($cells[$i] eq "1") {
                $cells[$i] = "a".$dir;
            } else {
                die "Unexpected cell $cells[$i]";
            }
            $i++;
        }
        print join(",", @cells), "\n";
    }
}
