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

// Find all psi-numbers in sums of copies of minimal spaces.
//
// Erratum. In Table 15, row 4 needs to be removed, "1" needs to be added to row 3
// column 1, and "(12,30)" in row 3 column 1 needs to be changed to "(14,34)".
// Thus, by Theorem 9 the sum space on just three copies of any Kuratowski space is full,
// for by Table 8, intersecting psi-numbers {44,62}, {65,67}, and {24,40} produces
// psi-numbers 24, 40, and 1, respectively, and intersecting psi-numbers {31,46},
// {31,48}, and {13,20} produces psi-numbers 13, 20, and 6, respectively.

// 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    "psi-number_intersections.h"


int main(int argc, const char * argv[])
{
    int     j, k, m, copies;
    int   **first_appearance;

// Load all psi-numbers present in the minimal space into an array.
// The discrete spaces {0} and {0,1} are trivial so we ignore them.

    static const int    min_GE[8] = {42,44,62,63,65,67,69,70};
    static const int    min_KD[14] = {31,46,48,59,60,62,63,64,65,66,67,68,69,70};
    static const int    min_OU[6] = {62,63,65,67,69,70};
    static const int    min_ED[5] = {61,65,67,69,70};
    static const int    min_EO[4] = {65,67,69,70};
    static const int    min_P_non_i[5] = {59,60,68,69,70};

// We use the index below to record array lengths (for looping purposes).

    static const int    psi_count[8] = {0,0,5,4,5,6,8,14};

// GE()     space type
// -----    ----------
// 1        D
// 2        P
// 3        EO
// 4        ED
// 5        OU
// 6        GE
// 7        KD

// first_appearance[space type][psi] = copies of X needed for psi-number psi to appear

    first_appearance = (int **)malloc(8 * sizeof(int *));
    if (first_appearance==0)
    {
        printf("\nCould not allocate space for first_appearance.\n");
        exit(0);
    }
    for (j=0; j<8; j++)
    {
        first_appearance[j] = (int *)malloc(71 * sizeof(int));
        if (first_appearance[j]==0)
        {
            printf("\nCould not allocate space for first_appearance[%d].\n", j);
            exit(0);
        }
        for (k=0; k<71; k++) first_appearance[j][k] = 0;
    }

// Enter initial data for the case of a single copy of X.

    for (j=2; j<8; j++)
        for (k=0; k<psi_count[j]; k++)
            switch (j)
            {
                case 2:
                    first_appearance[j][min_P_non_i[k]] = 1;
                    break;
                case 3:
                    first_appearance[j][min_EO[k]] = 1;
                    break;
                case 4:
                    first_appearance[j][min_ED[k]] = 1;
                    break;
                case 5:
                    first_appearance[j][min_OU[k]] = 1;
                    break;
                case 6:
                    first_appearance[j][min_GE[k]] = 1;
                    break;
                case 7:
                    first_appearance[j][min_KD[k]] = 1;
            }

// Compute Table 15.

    for (copies=2; copies<5; copies++)
        for (j=2; j<8; j++)
            for (k=1; k<70; k++)
                if (first_appearance[j][k] && (first_appearance[j][k] < copies))
                {
                    for (m=k+1; m<71; m++)
                    {
                        if (first_appearance[j][m] && (first_appearance[j][m] < copies))
                        {
                            if (first_appearance[j][psi_number_intersections[k][m]]) continue;
                            first_appearance[j][psi_number_intersections[k][m]] = copies;
                        }
                    }
                }

// Print the results.

    for (copies=2; copies<5; copies++)
    {
        printf("Case n = %d.\n\n", copies);
        for (j=2; j<8; j++)
        {
            switch (j)
            {
                case 2:
                    printf("P: ");
                    break;
                case 3:
                    printf("EO: ");
                    break;
                case 4:
                    printf("ED: ");
                    break;
                case 5:
                    printf("OU: ");
                    break;
                case 6:
                    printf("GE: ");
                    break;
                case 7:
                    printf("KD: ");
            }
            for (k=1; k<69; k++)
            {
                if (first_appearance[j][k] == copies) printf("%d ", k);
            }
            printf("\n");
        }
        printf("\n");
    }

    for (j=0; j<8; j++) free(first_appearance[j]);
    free(first_appearance);
}
