// main.c
// Copyright (C) 2023 Mark Bowron

// Find the ordering under set inclusion on all psi-numbers.

// 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 3 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.


#include    <stdio.h>
#include    <stdlib.h>
#include    <inttypes.h>
#include    <stdbool.h>
#include    <string.h>
#include    "set_operators.h"
#include    "set_families.h"
#include    "set_relations.h"
#include    "collapses.h"
#include    "topologies.h"
#include    "psi-numbers.h"


int main(int argc, const char * argv[])
{
    int         j, k, l;
    int      ***psi, **psi_subset;
    int       **copy, **tc, **ab, **tr; // For transitive reduction only.

    psi = (int ***)malloc(71 * sizeof(int **));
    if (psi==0)
    {
        printf("\nCould not allocate space for psi.\n");
        exit(0);
    }
    psi_subset = (int **)malloc(71 * sizeof(int *));
    if (psi_subset==0)
    {
        printf("\nCould not allocate space for psi_subset.\n");
        exit(0);
    }
    copy = (int **)malloc(71 * sizeof(int *));
    if (copy==0)
    {
        printf("\nCould not allocate space for copy.\n");
        exit(0);
    }
    tc = (int **)malloc(71 * sizeof(int *));
    if (tc==0)
    {
        printf("\nCould not allocate space for tc.\n");
        exit(0);
    }
    ab = (int **)malloc(71 * sizeof(int *));
    if (ab==0)
    {
        printf("\nCould not allocate space for ab.\n");
        exit(0);
    }
    tr = (int **)malloc(71 * sizeof(int *));
    if (tr==0)
    {
        printf("\nCould not allocate space for tr.\n");
        exit(0);
    }
    for (j=0; j<71; j++)
    {
        psi[j] = (int **)malloc(34 * sizeof(int *));
        if (psi[j]==0)
        {
            printf("\nCould not allocate space for psi[%d].\n", j);
            exit(0);
        }
        for (k=0; k<34; k++)
        {
            psi[j][k] = (int *)malloc(34 * sizeof(int));
            if (psi[j][k]==0)
            {
                printf("\nCould not allocate space for psi[%d][%d].\n", j, k);
                exit(0);
            }
            for (l=0; l<34; l++) psi[j][k][l] = 0;
        }
        psi_subset[j] = (int *)malloc(71 * sizeof(int));
        if (psi_subset[j]==0)
        {
            printf("\nCould not allocate space for psi_subset[%d].\n", j);
            exit(0);
        }
        copy[j] = (int *)malloc(71 * sizeof(int));
        if (copy[j]==0)
        {
            printf("\nCould not allocate space for copy[%d].\n", j);
            exit(0);
        }
        tc[j] = (int *)malloc(71 * sizeof(int));
        if (tc[j]==0)
        {
            printf("\nCould not allocate space for tc[%d].\n", j);
            exit(0);
        }
        ab[j] = (int *)malloc(71 * sizeof(int));
        if (ab[j]==0)
        {
            printf("\nCould not allocate space for ab[%d].\n", j);
            exit(0);
        }
        tr[j] = (int *)malloc(71 * sizeof(int));
        if (tr[j]==0)
        {
            printf("\nCould not allocate space for tr[%d].\n", j);
            exit(0);
        }
        for (k=0; k<71; k++)
        {
            psi_subset[j][k] = 0;
            copy[j][k] = 0;
            tc[j][k] = 0;
            ab[j][k] = 0;
            tr[j][k] = 0;
        }
    }

// Copy psi-number matrices into psi[].

    for (j=0; j<71; j++)
        for (k=0; k<34; k++)
            memcpy(psi[j][k],psi_numbers[j][k],sizeof(psi_numbers[j][k]));

// Exhaustively find all psi-number inclusions and store the results in psi_subset.

    for (j=1; j<71; j++)
        for (k=1; k<71; k++)
            if (matrixSubset(psi[j],psi[k],34)) psi_subset[j][k] = 1;

// Print every inclusion in the transitive reduction of psi_subset.

    getTransitiveReduction(psi_subset,copy,tc,ab,tr,71);

    for (j=1; j<71; j++)
    {
        for (k=1; k<71; k++)
            if (tr[j][k]) printf("%2d < %2d\n",j,k);
        printf("\n");
    }

    for (j=0; j<71; j++)
    {
        for (k=0; k<34; k++) free(psi[j][k]);
        free(psi[j]);
        free(psi_subset[j]);
        free(copy[j]);
        free(tc[j]);
        free(ab[j]);
        free(tr[j]);
    }
    free(psi);
    free(psi_subset);
    free(copy);
    free(tc);
    free(ab);
    free(tr);
}
