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

// Produce header file psi-number_intersections.h

// 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;
    int  ***psi, **intersection, **psi_intersection;
    KFenum  key = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
                    20,21,22,23,24,25,26,27,28,29,30,31,32,33};
    KFenum *kf = &key;

    psi = (int ***)malloc(71 * sizeof(int **));
    if (psi==0)
    {
        printf("\nCould not allocate space for psi.\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);
            }
        }
    }
    intersection = (int **)malloc(34 * sizeof(int *));
    if (intersection==0)
    {
        printf("\nCould not allocate space for intersection.\n");
        exit(0);
    }
    for (j=0; j<34; j++)
    {
        intersection[j] = (int *)malloc(34 * sizeof(int));
        if (intersection[j]==0)
        {
            printf("\nCould not allocate space for intersection[%d].\n", j);
            exit(0);
        }
        for (k=0; k<34; k++) intersection[j][k] = 0;
    }
    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]));

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

// psi[n][x][y] = 1 iff the xth and yth sets in the canonical order on KF(A) are equal.
//
// We intersect all psi[] matrices pairwise and compute the psi-numbers of these
// intersections.

// Compute the psi-number of every possible intersection of psi-numbers.

    for (j=1; j<71; j++)
        for (k=1; k<71; k++)
        {
            matrixIntersect(psi[j],psi[k],intersection,34);
            psi_intersection[j][k] = PsiArray(intersection,kf);
        }

// Print psi-number_intersections.h

    printf("// psi-number_intersections.h\n");
    printf("// Copyright (C) 2023 Mark Bowron\n\n");
    printf("// Psi-numbers of intersections.\n\n");
    printf("// This program is free software: you can redistribute it and/or modify\n");
    printf("// it under the terms of the GNU General Public License as published by\n");
    printf("// the Free Software Foundation, either version 3 of the License, or\n");
    printf("// (at your option) any later version.\n\n");
    printf("// This program is distributed in the hope that it will be useful,\n");
    printf("// but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
    printf("// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
    printf("// GNU General Public License for more details.\n\n");
    printf("static const int psi_number_intersections[71][71] = {\n");

    for (j=0; j<71; j++)
    {
        printf("{");
        for (k=0; k<70; k++) printf("%d,", psi_intersection[j][k]);
        if (j<70) printf("%d},\n", psi_intersection[j][70]);
        else printf("%d}};\n\n", psi_intersection[j][70]);
    }

    for (j=0; j<71; j++)
    {
        for (k=0; k<34; k++) free(psi[j][k]);
        free(psi[j]);
        free(psi_intersection[j]);
    }
    free(psi);
    free(psi_intersection);
    for (j=0; j<34; j++) free(intersection[j]);
    free(intersection);
}
