/*    TEMPL4
TESTING template CLAUSE */

#include <math.h>
#include <stdlib.h>
#include <stdio.h>

static void templ441();
static void templ442();

static void ansyes(const char tname[]);
static void ansno(const char tname[]);

static int NL = 1000;
static int ER = 10000;
static int erri, i, j, ia, ib, ic, ja, jb, jc, k, m, n, mb, nb, mc, nc;

int main(int an, char **as)
{
    printf("=== START OF TEMPL4 ======================\n");
    /* TEMPLATE A4[BLOCK][BLOCK][BLOCK][BLOCK]
       ALIGN B4[i][j][k][l] WITH A4[i+2][j][k][l+3]
       ALIGN C2[i][j] WITH A4[i+2][2][3][l+3]        */
    templ441();
    /* TEMPLATE A4[BLOCK][BLOCK][BLOCK][BLOCK]
       ALIGN B4[i][j][k][l] WITH A4[l][i][j][k]
       ALIGN C4[i][j][k][l] WITH A4[i+2][j][k][l+3]  */
    templ442();
    printf("=== END OF TEMPL4 ========================\n");
    return 0;
}

/* ---------------------------------------------TEMPL441*/
/* TEMPLATE A4[BLOCK][BLOCK][BLOCK][BLOCK]
   ALIGN B4[i][j][k][l] WITH A4[i+2][j][k][l+3]
   ALIGN C2[i][j] WITH A4[i+2][2][3][l+3]        */
void templ441()
{
    #define AN1 7
    #define AN2 7
    #define AN3 7
    #define AN4 7
    #define BN1 2
    #define BN2 2
    #define BN3 2
    #define BN4 2
    #define CN1 4
    #define CN2 4

    int k1i = 1, k2i = 0, k3i = 0, k4i = 0, li = 2;
    int k1j = 0, k2j = 1, k3j = 0, k4j = 0, lj = 0;
    int k1n = 0, k2n = 0, k3n = 1, k4n = 0, ln = 0;
    int k1m = 0, k2m = 0, k3m = 0, k4m = 1, lm = 3;
    int kc1i = 1, kc2i = 0, kc3i = 0, kc4i = 0, lci = 2;
    int kc1j = 0, kc2j = 0, kc3j = 0, kc4j = 0, lcj = 2;
    int kc1n = 0, kc2n = 0, kc3n = 0, kc4n = 0, lcn = 3;
    int kc1m = 0, kc2m = 1, kc3m = 0, kc4m = 0, lcm = 3;
    char tname[] = "templ441 ";

    #pragma dvm template[AN1][AN2][AN3][AN4] distribute[block][block][block][block]
    void *A4;
    #pragma dvm array align([i][j][n][m] with A4[k1i*i+li][k2j*j+lj][k3n*n+ln][k4m*m+lm])
    int B4[BN1][BN2][BN3][BN4];
    #pragma dvm array align([i][j] with A4[kc1i*i+lci][lcj][lcn][kc2m*j+lcm])
    int C2[CN1][CN2];

    erri = ER;
    #pragma dvm actual(erri)

    #pragma dvm region
    {
    #pragma dvm parallel([m][n][j][i] on B4[i][j][n][m])
    for (m = 0; m < BN4; m++)
        for (n = 0; n < BN3; n++)
            for (j = 0; j < BN2; j++)
                for (i = 0; i < BN1; i++)
                    B4[i][j][n][m] = (i*NL/10+j*NL/100+n*NL/1000+m);

    #pragma dvm parallel([j][i] on C2[i][j])
    for (j = 0; j < CN2; j++)
        for (i = 0; i < CN1; i++)
            C2[i][j] = (i*NL+j);

    #pragma dvm parallel([m][n][j][i] on A4[i][j][n][m]) private(ib, jb, nb, mb, ic, jc, erri)
    for (m = 0; m < AN4; m++)
        for (n = 0; n < AN3; n++)
            for (j = 0; j < AN2; j++)
                for (i = 0; i < AN1; i++)
                {
                    if (((i-li) == (((i-li)/k1i) * k1i)) &&
                            ((j-lj) == (((j-lj)/k2j) *k2j)) &&
                            ((n-ln) == (((n-ln)/k3n) * k3n)) &&
                            ((m-lm) == (((m-lm)/k4m) *k4m)) &&
                            (((i-li)/k1i) >= 0) &&
                            (((j-lj)/k2j) >= 0) &&
                            (((n-ln)/k3n) >= 0) &&
                            (((m-lm)/k4m) >= 0) &&
                            (((i-li)/k1i) < BN1) &&
                            (((j-lj)/k2j) < BN2) &&
                            (((n-ln)/k3n) < BN3) &&
                            (((m-lm)/k4m) < BN4))
                    {
                        ib = (i-li)/k1i;
                        jb = (j-lj)/k2j;
                        nb = (n-ln)/k3n;
                        mb = (m-lm)/k4m;
                        if (B4[ib][jb][nb][mb] != (ib*NL/10+jb*NL/100+nb*NL/1000+mb))
                            erri = i*NL/10 + j*NL/100+ n*NL/1000+ m;
                    }
                    if ((j == lcj) && (n == lcn) &&
                            ((i-lci) == (((i-lci)/kc1i) * kc1i)) &&
                            ((m-lcm) == (((m-lcm)/kc2m) *kc2m)) &&
                            (((i-lci)/kc1i) >= 0) &&
                            (((m-lcm)/kc2m) >= 0) &&
                            (((i-lci)/kc1i) < CN1) &&
                            (((m-lcm)/kc2m) < CN2))
                    {
                        ic = (i-lci)/kc1i;
                        jc = (m-lcm)/kc2m;
                        if (C2[ic][jc] != (ic*NL+jc))
                            erri = i;
                    }
                }
    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);

    #undef AN1
    #undef AN2
    #undef AN3
    #undef AN4
    #undef BN1
    #undef BN2
    #undef BN3
    #undef BN4
    #undef CN1
    #undef CN2
}

/* ---------------------------------------------TEMPL442*/
/* TEMPLATE A4[BLOCK][BLOCK][BLOCK][BLOCK]
   ALIGN B4[i][j][k][l] WITH A4[l][i][j][k]
   ALIGN C4[i][j][k][l] WITH A4[i+2][j][k][l+3]  */
void templ442()
{
    int AN1 = 7, AN2 = 7, AN3 = 7, AN4 = 7;
    int BN1 = 2, BN2 = 2, BN3 = 2, BN4 = 2;
    int CN1 = 4, CN2 = 4, CN3 = 4, CN4 = 4;

    int k1i = 0, k2i = 0, k3i = 0, k4i = 1, li = 0;
    int k1j = 1, k2j = 0, k3j = 0, k4j = 0, lj = 0;
    int k1n = 0, k2n = 1, k3n = 0, k4n = 0, ln = 0;
    int k1m = 0, k2m = 0, k3m = 1, k4m = 0, lm = 0;
    int kc1i = 1, kc2i = 0, kc3i = 0, kc4i = 0, lci = 2;
    int kc1j = 0, kc2j = 1, kc3j = 0, kc4j = 0, lcj = 0;
    int kc1n = 0, kc2n = 0, kc3n = 1, kc4n = 0, lcn = 0;
    int kc1m = 0, kc2m = 0, kc3m = 0, kc4m = 1, lcm = 3;

    char tname[] = "templ442 ";

    #pragma dvm template[AN1][AN2][AN3][AN4] distribute[block][block][block][block]
    void *A4;
    #pragma dvm array
    int (*B4)[BN2][BN3][BN4];
    #pragma dvm array
    int (*C4)[CN2][CN3][CN4];

    B4 = malloc(sizeof(int[BN1][BN2][BN3][BN4]));
    C4 = malloc(sizeof(int[CN1][CN2][CN3][CN4]));
    #pragma dvm realign(B4[i][j][n][m] with A4[k4i*m+li][k1j*i+lj][k2n*j+ln][k3m*n+lm])
    #pragma dvm realign(C4[i][j][n][m] with A4[kc1i*i+lci][kc2j*j+lcj][ kc3n*n+lcn][kc4m*m+lcm])

    erri = ER;
    #pragma dvm actual(erri)

    #pragma dvm region
    {
    #pragma dvm parallel([m][n][j][i] on B4[i][j][n][m])
    for (m = 0; m < BN4; m++)
        for (n = 0; n < BN3; n++)
            for (j = 0; j < BN2; j++)
                for (i = 0; i < BN1; i++)
                    B4[i][j][n][m] = (i*NL/10+j*NL/100+n*NL/1000+m);

    #pragma dvm parallel([m][n][j][i] on C4[i][j][n][m])
    for (m = 0; m < CN4; m++)
        for (n = 0; n < CN3; n++)
            for (j = 0; j < CN2; j++)
                for (i = 0; i < CN1; i++)
                    C4[i][j][n][m] = (i*NL/10+j*NL/100+n*NL/1000+m);

    #pragma dvm parallel([m][n][j][i] on A4[i][j][n][m]) private(ib, jb, nb, mb, ic, jc, nc, mc, erri)
    for (m = 0; m < AN4; m++)
        for (n = 0; n < AN3; n++)
            for (j = 0; j < AN2; j++)
                for (i = 0; i < AN1; i++)
                {
                    if (((i-li) == (((i-li)/k4i) * k4i)) &&
                            ((j-lj) == (((j-lj)/k1j) *k1j)) &&
                            ((n-ln) == (((n-ln)/k2n) * k2n)) &&
                            ((m-lm) == (((m-lm)/k3m) *k3m)) &&
                            (((i-li)/k4i) >= 0) &&
                            (((j-lj)/k1j) >= 0) &&
                            (((n-ln)/k2n) >= 0) &&
                            (((m-lm)/k3m) >= 0) &&
                            (((i-li)/k4i) < BN4) &&
                            (((j-lj)/k1j) < BN1) &&
                            (((n-ln)/k2n) < BN2) &&
                            (((m-lm)/k3m) < BN3))
                    {
                        mb = (i-li)/k4i;
                        ib = (j-lj)/k1j;
                        jb = (n-ln)/k2n;
                        nb = (m-lm)/k3m;
                        if (B4[ib][jb][nb][mb] != (ib*NL/10+jb*NL/100+nb*NL/1000+mb))
                            erri = i*NL/10 + j*NL/100+ n*NL/1000+ m;
                    }
                    if (
                            ((i-lci) == (((i-lci)/kc1i) * kc1i)) &&
                            ((j-lcj) == (((j-lcj)/kc2j) * kc2j)) &&
                            ((n-lcn) == (((n-lcn)/kc3n) * kc3n)) &&
                            ((m-lcm) == (((m-lcm)/kc4m) *kc4m)) &&
                            (((i-lci)/kc1i) >= 0) &&
                            (((j-lcj)/kc2j) >= 0) &&
                            (((n-lcn)/kc3n) >= 0) &&
                            (((m-lcm)/kc2m) >= 0) &&
                            (((i-lci)/kc1i) < CN1) &&
                            (((j-lcj)/kc2j) < CN2) &&
                            (((n-lcn)/kc3n) < CN3) &&
                            (((m-lcm)/kc2m) < CN2))
                    {
                        ic = (i-lci)/kc1i;
                        jc = (j-lcj)/kc2j;
                        nc = (n-lcn)/kc3n;
                        mc = (m-lcm)/kc4m;
                        if (C4[ic][jc][nc][mc] != (ic*NL/10+jc*NL/100+nc*NL/1000+mc))
                            erri = i*NL/10 + j*NL/100+ n*NL/1000+ m;
                    }
                }
    }

    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);

    free(B4);
    free(C4);
}

void ansyes(const char name[])
{
    printf("%s  -  complete\n", name);
}

void ansno(const char name[])
{
    printf("%s  -  ***error\n", name);
}
