\documentclass[12pt, a4paper]{scrartcl}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Packages
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage[margin=0.5in]{geometry}

\usepackage[pdftex]{hyperref}
\usepackage{multicol}

\usepackage{xinttools}
\usepackage[nomessages]{fp}
\usepackage{tabularx}
\usepackage{tcolorbox}

\setlength{\parindent}{0pt}

\usepackage[pdftex]{insdljs}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parameter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Board width and height (should not be changed)
\def\boardWidth{8}
\def\boardHeight{8}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Javascript
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{insDLJS}[]{JSDateiname}{chess}

const GAME_DESC = "Chess is a two player strategy game. The goal is to attack the enemy king,\
while not leaving him an escape option. Each piece has a specific move pattern,\
leaving a lot of room for different combinations and play styles.";

% Outside variables
const BOARD_WIDTH = AFMakeNumber(\boardWidth);
const BOARD_HEIGHT = AFMakeNumber(\boardHeight);
const SCREEN_TEXT_SIZE = 500;
const PLAYBACK_SPEED = 200;

% Constants
% Accessing variables
const M = 0;
const N = 1;
% The piece indices
const PIECE = 0;
const EMPTY = "";
const KING = 0;
const QUEEN = 1;
const BISHOP = 2;
const KNIGHT = 3;
const ROOK = 4;
const PAWN = 5;
% The two different colors, using -1 and 1 so they can be reused as the direction of play
const COLOR = 1;
const WHITE = -1;
const NONE = 0;
const BLACK = 1;
% Keeps track of the number of moves made by a piece
const MOVES = 2;
const UNMOVED = 0;

% Globals
% The game board array
var complBoard = new Array();
% Indicates whether one player is checked
var check = false;
% Indicates whether the game is over and one player lost
var checkmate = false;
% Indicates whether the game is over and it is a draw
var stalemate = false;
% Saves the last made selection by any player (each turn is a two step process).
var lastSelection = [];
% Keeps track whos turn it is
var currentTurn = WHITE;
% If this is non empty there is a pawn at these coords that needs to be promoted
var promotionPos = [];
% If this is non -1 there is a pawn at these coords that might be taken via en passant (one turn)
var enpassant = [-1, -1];
% Indicates how many cells were highlighted in the last turn, used for checkmate
var highlightCount = 0;

% Array for keeping track where the king is located. Needed for check tests.
var kingPos = [
    [7, 4],
    [-1, -1], % padding
    [0, 4]
];

% PGN parsing
% All input moves
var movesToProcess = [];
% The interval to keep applying moves
var playInterval;
% Save move state (show moves + the actual move)
var processBool = true;
% The move data after converting to internal representation
var conversion = [];
% Indicate whether there is a pawn to be promoted
var promotionIndex = 0;

% Game Data
% The symbol array, each piece gets one symbol. Since the utf8 chess pieces do not work
% default asccii letters are used
const PIECE_SYMBOLS = new Array(
    "K", "Q", "B", "N", "R", "P"
);

% The moveset of each piece, indicating in which direction a piece can move
const DIRS = [
    [ % King
        [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1], [1, -1]
    ],
    [ % Queen
        [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1], [1, -1]
    ],
    [ % Bishop
        [1, 1], [-1, 1], [-1, -1], [1, -1]
    ],
    [ % Knight               | |1| |2| |
        [ 2, -1], % 1        -----------
        [ 2,  1], % 2        |8| | | |3|
        [ 1,  2], % 3        -----------
        [-1,  2], % 4        | | |x| | |
        [-2,  1], % 5        -----------
        [-2, -1], % 6        |7| | | |4|
        [-1, -2], % 7        -----------
        [ 1, -2]  % 8        | |6| |5| |
    ],
    [ % Rook
        [1, 0], [0, 1], [-1, 0], [0, -1]
    ]
];

% Color data
const CELL_COLORS = new Array(
    [ "RGB", 0.8431, 0.6549, 0.3803 ],
    [ "RGB", 0.5686, 0.3058, 0.1098 ]
);

const TEXT_COLORS = new Array(
    color.white,
    color.black
);

% Highlightcolor for selection
const SELECTION_COLOR = [ "RGB", 0.984, 0.800, 0.176 ];
% Highlightcolor for possible moves
const POSS_MOVE_COLOR = [ "RGB", 0.54, 0.800, 0.176 ];
% Highlightcolor for check
const CHECK_COLOR = [ "RGB", 0.9, 0.100, 0.176 ];

%%%%%%%%%%
% Helper %
%%%%%%%%%%
/**
 * Returns a random number between 0 and the param.
 * @param {Number} max The upperbound.
 * @param {Number} Return a random integer.
 */
function getRandomInt(max) {
    return Math.floor(Math.random() * max);
}

/**
 * Calculates the sign of the given number.
 * This function is needed, since Math.sign is not available.
 * @param {Number} x The number in question.
 * @param {Number} Returns the sign of the parameter x.
 */
function sign(x) {
    return ((x > 0) - (x < 0)) || +x;
};

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initialisation and Restart %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/**
 * Initialise the default game state.
 */
function initialise() {
    % Fill the array with the default content and infos
    for (var m = 0; m < BOARD_HEIGHT; m++) {
        var row = new Array();
        for (var n = 0; n < BOARD_WIDTH; n++) {
            row.push([EMPTY, NONE, UNMOVED]);
        }
        complBoard.push(row);
    }

    % Add the pieces for both players
    addPieces();

    % Init the GUI
    initialiseButtons();

    drawAll();
    printInfoText("Ready to play, good luck.");
}

/**
 * Initialise all buttons from the GUI.
 * For example add callbacks and set the correct colors.
 */
function initialiseButtons() {
    % Disables the rectangle around a button after the click
    app.focusRect = false;

    % Set the callbacks and attributes of each selectable cell
    var funcName = "move";
    for (var m = 0; m < BOARD_WIDTH; m++) {
        for (var n = 0; n < BOARD_HEIGHT; n++) {
            var callbackName = funcName + "(" + m.toString() + "," + n.toString() + ");";
            var c = this.getField("cell" + m + "-" + n);
            c.setAction("MouseDown", callbackName);
            c.alignment = "center";
            c.textSize = SCREEN_TEXT_SIZE / (BOARD_WIDTH * 3);
            c.borderWidth = 4;
        }
    }

    % Promotion buttons
    for (var i = 0; i < 4; i++) {
        var cell = this.getField("promote" + i);
        cell.setAction("MouseDown", "promotePawn(" + i.toString() + ")");
        cell.value = PIECE_SYMBOLS[QUEEN + i];
        cell.hidden = true;
        cell.alignment = "center";
    }

    % Process button setup
    var callback = "this.getField('process').setFocus();";
    this.getField("process").setAction("MouseDown", callback);
    this.getField("process").setAction("MouseUp", "processMoves();");

    % Restart button setup
    this.getField("restart").setAction("MouseDown", "restart();");

    % Info field setup
    this.getField("info").fillColor = color.transparent;
    this.getField("info").borderColor = color.transparent;

    % Tooltip button setup
    this.getField("tooltipbtn").setAction("MouseDown", "tooltip(true);");
    this.getField("tooltipbtn").setAction("MouseUp", "tooltip(false);");
}

/**
 * Restart the game by reseting everything to default.
 */
function restart() {
    % Remove focus so the cursor is not shown
    this.getField("info").setFocus();

    if (movesToProcess.length != 0) {
        printInfoText("Can not restart! Wait for animation to finish!");
        return;
    }

    % Reset game state
    check = false;
    checkmate = false;
    stalemate = false;
    % Reset turn data
    currentTurn = WHITE;
    lastSelection = [];
    highlightCount = 0;
    % Reset piece data
    promotionPos = [];
    enpassant = [-1, -1];
    kingPos = [[7, 4], [-1, -1], [0, 4]];

    % Clear the board
    for (var m = 2; m < BOARD_HEIGHT - 2; m++) {
        for (var n = 0; n < BOARD_WIDTH; n++) {
             complBoard[m][n] = [EMPTY, NONE, UNMOVED];
        }
    }

    % Add the pieces for both players
    addPieces();

    drawAll();
    printInfoText("Restarted the game.");
}

/**
 * Add all pieces to the board.
 * These are setup in the typical chess formation, white being bottom.
 */
function addPieces() {
    % Init PAWNs
    for (var n = 0; n < BOARD_WIDTH; n++) {
        complBoard[1][n] = [PIECE_SYMBOLS[PAWN], BLACK, UNMOVED];
        complBoard[BOARD_HEIGHT - 2][n] = [PIECE_SYMBOLS[PAWN], WHITE, UNMOVED];
    }

    % Init ROOKs, KNIGHTs, BISHOPs
    const PIECES = [PIECE_SYMBOLS[ROOK], PIECE_SYMBOLS[KNIGHT], PIECE_SYMBOLS[BISHOP]];
    for (var n = 0; n < PIECES.length; n++) {
        complBoard[0][n] = [PIECES[n], BLACK, UNMOVED];
        complBoard[0][BOARD_WIDTH - n - 1] = [PIECES[n], BLACK, UNMOVED];
        complBoard[BOARD_HEIGHT - 1][n] = [PIECES[n], WHITE, UNMOVED];
        complBoard[BOARD_HEIGHT - 1][BOARD_WIDTH - n - 1] = [PIECES[n], WHITE, UNMOVED];
    }

    % Init KINGs and QUEENs
    complBoard[0][3] = [PIECE_SYMBOLS[QUEEN], BLACK, UNMOVED];
    complBoard[0][4] = [PIECE_SYMBOLS[KING], BLACK, UNMOVED];
    complBoard[BOARD_HEIGHT - 1][3] = [PIECE_SYMBOLS[QUEEN], WHITE, UNMOVED];
    complBoard[BOARD_HEIGHT - 1][4] = [PIECE_SYMBOLS[KING], WHITE, UNMOVED];
}

/**
 * Enable or disable the tooltip
 *
 * @param {Boolean} on Enable or disable tooltip
 */
function tooltip(on) {
    if (on) {
        % Move the tooltip field to the center of the screen
        % and adjust the size so the text can be displayed
        var field = this.getField("tooltiptxt");
        field.delay = true;
        field.hidden = false;
        field.value = GAME_DESC;

        field.multiline = true;
        field.textSize = 16;
        field.fillColor = color.gray;
        % height 842, width 596
        % upper-left x, upper-left y, lower-right x and lower-right y
        field.rect = [128, 601, 468, 401];

        field.delay = false;
    } else {
        % Remove the field such that it is not visible
        var field = this.getField("tooltiptxt");
        field.delay = true;
        field.hidden = true;
        field.value = "";

        field.multiline = false;
        field.fillColor = color.gray;
        field.rect = [0, 0, 0, 0];

        field.delay = false;
    }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Gamelogic                     %
% Move validation and execution %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/**
 * This is the main function that processes the player input.
 * There are three states:
 * 1. The player did not yet select a piece to play.
 * This leads to a check whether the now selected cell contains a piece that the player
 * can actually play, then all possible moves with this piece are calculated and highlighted.
 * The selection is saved afterwards.
 * 2. The player already selected a cell with his last input.
 * In this case it is simply checked whether the new selection is highlighted (from the last step).
 * If so the move is valid therefore executed. There are a few special cases, like
 * en passant, pawn promotion or castling in which another cells content must be adjusted.
 * At the end of the move execution it is tested whether the enemy king is checked and/or the game
 * is over due to checkmate or stalemate.
 * 3. If the player selects the same cell twice the highlight is reversed
 * after the second selection.
 *
 * OBACHT: Threefold repetition is not tracked since the player needs to claim
 * the draw but may continue playing.
 *
 * @param {Number} m The m position (height).
 * @param {Number} n The n position (width).
 */
function move(m, n) {
    this.getField("tooltiptxt").setFocus();

    % Test for special cases in which no move processing should be done
    if (checkmate) {
        printInfoText("It is checkmate, the game is over!");
        return;
    }
    if (stalemate) {
        printInfoText("It is a stalemate, the game is over!");
        return;
    }
    if (promotionPos.length > 0) {
        printInfoText("You need to promote your pawn.");
        return;
    }

    % If no selection was made, save this press and show potential destinations
    if (lastSelection.length == 0) {
        % Validate selection and highlight it if valid
        if (validSelection(m, n)) {
            lastSelection = [m, n];
            % Highlight selection
            highlight(m, n, SELECTION_COLOR, true);
            % Highlight possible moves
            highlightValidMoves(true);
            printInfoText("Piece selected.");
        }
    }
    % If a selection is already saved check if the move is valid and if so move the piece there
    else if (validMove(m, n)) {
        % Remove selection highlight
        highlight(m, n, 0, false);
        % Remove highlight of possible moves
        highlightValidMoves(false);

        % Move piece
        complBoard[m][n] = complBoard[lastSelection[M]][lastSelection[N]];
        % The piece was moved, mark it as such
        complBoard[m][n][MOVES] = complBoard[lastSelection[M]][lastSelection[N]][MOVES] + 1;
        complBoard[lastSelection[M]][lastSelection[N]] = [EMPTY, NONE, UNMOVED];
        % Redraw
        draw(m, n);
        draw(lastSelection[M], lastSelection[N]);

        if (complBoard[m][n][PIECE] == PIECE_SYMBOLS[KING]) {
            % King was moved upate his position
            kingPos[currentTurn + 1] = [m, n];

            % Special case: castling
            % If the moved piece is the king and he castled also move the rook
            if (Math.abs(lastSelection[N] - n) == 2) {
                % Check if left or right rook needs to move
                var direction = sign(lastSelection[N] - n);
                var rookN = direction == 1 ? 0 : 7;
                % Calc new rook position
                var newN = lastSelection[N] - direction;
                complBoard[m][newN] = complBoard[m][rookN];
                % The rook was moved the first time
                complBoard[m][newN][MOVES] = 1;
                complBoard[m][rookN] = [EMPTY, NONE, UNMOVED];
                draw(m, newN);
                draw(m, rookN);
            }
        }

        if (complBoard[m][n][PIECE] == PIECE_SYMBOLS[PAWN]) {
            % Special case: en passant
            % Delete the pawn that was captured by en passant
            if (m == (enpassant[M] + currentTurn) && n == enpassant[N]) {
                complBoard[enpassant[M]][enpassant[N]] = [EMPTY, NONE, UNMOVED];
                draw(enpassant[M], enpassant[N]);
            }
            enpassant = [-1, -1];
            % Special case: pawn promotion
            if (m == 7 || m == 0) {
                showPromotionButtons(true);
                promotionPos = [m, n];
            }
            % Special case: en passant - preparation
            if (Math.abs(lastSelection[M] - m) == 2) {
                enpassant = [m, n];
            }
        } else {
            % Reset en passant, since it only is allowed for one turn
            enpassant = [-1, -1];
        }

        % Disable check highlight from last player
        highlight(kingPos[currentTurn + 1][M], kingPos[currentTurn + 1][N], CHECK_COLOR, false);
        % Checktest and next turn
        if (currentTurn == WHITE) {
            % Test if the enemy is checked
            check = testCheck(BLACK);
            highlight(kingPos[BLACK + 1][M], kingPos[BLACK + 1][N], CHECK_COLOR, check);
            % Advance turn
            currentTurn = BLACK;
        } else {
            % Test if the enemy is checked
            check = testCheck(WHITE);
            highlight(kingPos[WHITE + 1][M], kingPos[WHITE + 1][N], CHECK_COLOR, check);
            % Advance turn
            currentTurn = WHITE;
        }

        lastSelection = [];

        % Test if the player who has to play next, has any moves left.
        % If not it is either a stalemate or checkmate.
        var gameover = testGameover();
        if (check) {
            printInfoText("Check!");
            if (gameover) {
                checkmate = true;
                printInfoText("Checkmate!");
            }
        } else {
            printInfoText("Piece moved!");
            if (gameover) {
                stalemate = true;
                printInfoText("Stalemate!");
            }
        }
    }
    % If the input matches the already selected cell, remove selection
    else if (lastSelection[M] == m && lastSelection[N] == n) {
        % Remove selection highlight
        highlight(m, n, 0, false);
        % Remove highlight of possible moves
        highlightValidMoves(false);
        lastSelection = [];
        printInfoText("Unselected piece.");

        % Rehighlight the king is he is checked -> no move, so nothing has changed
        if (check) {
            highlight(
                kingPos[currentTurn + 1][M], kingPos[currentTurn + 1][N], CHECK_COLOR, check
            );
        }
    }
}

/**
 * Validate the selection by testing if the cell is non empty and not an enemy piece.
 * @param {Number} m The m position (height).
 * @param {Number} n The n position (width).
 */
function validSelection(m, n) {
    % Empty cell
    if (complBoard[m][n][PIECE] == EMPTY) {
        printInfoText("Field empty, could not select!");
        return false;
    }
    % Enemy piece
    else if (currentTurn != complBoard[m][n][COLOR]) {
        printInfoText("Thats an enemy piece, could not select!");
        return false;
    }

    return true;
}

/**
 * To check if a move is valid the bordercolor of the target cell that was selected is
 * checked, since it should be marked with POSS_MOVE_COLOR if the move would be valid.
 * It is not totally clear whether that is faster than just using math to check the
 * validity but since it also would be necessary to check if there is a piece between
 * source and target this approach at least saves a few lines of duplicated code.
 *
 * @param {Number} m The m position (height).
 * @param {Number} n The n position (width).
 */
function validMove(m, n) {
    % If the player selects one of his own pieces the move can not be valid
    if (currentTurn == complBoard[m][n][COLOR]) {
        printInfoText("Move not valid, thats your own piece!");
        return false;
    }

    % Sadly the equality test (==) does not work, since the borderColor has
    % more digits after the comma then POSS_MOVE_COLOR
    const EPSILON = 0.001;
    var equal = function(col1, col2) {
        return col1[1] - col2[1] < EPSILON &&
            col1[2] - col2[2] < EPSILON &&
            col1[3] - col2[3] < EPSILON;
    }

    % Retrieve the cell data
    % Just check if the cell is marked from the last selection
    var cell = this.getField("cell" + m + "-" + n);
    if (equal(cell.borderColor, POSS_MOVE_COLOR)) {
        return true;
    } else {
        printInfoText(
            complBoard[lastSelection[M]][lastSelection[N]][PIECE] + " can not move there."
        );
        return false;
    }

    return true;
}

/**
 * Enable or disable the highlight of all valid moves.
 * Therefore it is checked what piece is selected, afterwards all possible
 * moves are iterated and highlighted. The iteration starts at the piece
 * position in each valid direction until it hits an other piece.
 * Should that piece be of the same color the cell is not marked, since the player
 * can not remove his own pieces, otherwise the cell is highlighted.
 * OBACHT: PAWN and KING have multiple special cases
 *
 * @param {Boolen} enable Indicates whether the highlight should be enabled or disabled.
 */
function highlightValidMoves(enable) {
    % Pawn
    if (complBoard[lastSelection[M]][lastSelection[N]][PIECE] == PIECE_SYMBOLS[PAWN]) {
        var pieceColor = complBoard[lastSelection[M]][lastSelection[N]][COLOR];
        % Was the pawn already moved?
        const startPos = complBoard[lastSelection[M]][lastSelection[N]][MOVES] == UNMOVED;

        % Since black and white have the values 1 and -1 this calculation works
        var diffCol = function(tC, pC) { return sign(tC) == sign(pC) * -1 };
        var cellFree = function(tC, pC) { return tC == NONE };
        var doubStep = function(tC, pC) { return startPos && cellFree(tC, pC) }

        const CONDITION = 2;
        const positions = [
            % If there is an enemy across allow that move (opposite color)
            [pieceColor, -1, diffCol],
            [pieceColor, 1, diffCol],
            % Allow moving forward when the cell is empty
            [pieceColor, 0, cellFree],
            [pieceColor * 2, 0, doubStep]
        ];

        % Iterate all possible moves
        for (var i = 0; i < positions.length; i++) {
            % m and n values to test
            var m = lastSelection[M] + positions[i][M];
            var n = lastSelection[N] + positions[i][N];

            % Out of bounds check
            if (m < 0 || n < 0 || m >= BOARD_HEIGHT || n >= BOARD_WIDTH) {
                continue;
            }
            var targetColor = complBoard[m][n][COLOR];
            % Test if the jumped cell is free in case of a two cell movement
            if (Math.abs(positions[i][M]) == 2) {
                targetColor += complBoard[lastSelection[M] + pieceColor][n][COLOR];
            }

            % Test the different conditions
            % Guarantee that the player does resolve potential checks and does not check himself
            if (positions[i][CONDITION](targetColor, pieceColor) && noCheck(m, n, pieceColor)) {
                highlight(m, n, POSS_MOVE_COLOR, enable);
            }
        }

        % Check for en passant
        if (Math.abs(enpassant[N] - lastSelection[N]) == 1 &&
            enpassant[M] - lastSelection[M] == 0 &&
            noCheck(enpassant[M] + pieceColor, enpassant[N], pieceColor)
        ) {
            highlight(enpassant[M] + pieceColor, enpassant[N], POSS_MOVE_COLOR, enable);
        }
    }
    % Queen
    else if (complBoard[lastSelection[M]][lastSelection[N]][PIECE] == PIECE_SYMBOLS[QUEEN]) {
        loopPositions(DIRS[QUEEN], Math.max(BOARD_WIDTH, BOARD_HEIGHT), enable);
    }
    % Knight
    else if (complBoard[lastSelection[M]][lastSelection[N]][PIECE] == PIECE_SYMBOLS[KNIGHT]) {
        loopPositions(DIRS[KNIGHT], 2, enable);
    }
    % Rook
    else if (complBoard[lastSelection[M]][lastSelection[N]][PIECE] == PIECE_SYMBOLS[ROOK]) {
        loopPositions(DIRS[ROOK], Math.max(BOARD_WIDTH, BOARD_HEIGHT), enable);
    }
    % Bishop
    else if (complBoard[lastSelection[M]][lastSelection[N]][PIECE] == PIECE_SYMBOLS[BISHOP]) {
        loopPositions(DIRS[BISHOP], Math.max(BOARD_WIDTH, BOARD_HEIGHT), enable);
    }
    % King
    else if (complBoard[lastSelection[M]][lastSelection[N]][PIECE] == PIECE_SYMBOLS[KING]) {
        % The color of the currently selected piece
        var pieceColor = complBoard[lastSelection[M]][lastSelection[N]][COLOR];

        % Iterate all directions of this piece
        for (var i = 0; i < DIRS[KING].length; i++) {
            var m = lastSelection[M] + DIRS[KING][i][M];
            var n = lastSelection[N] + DIRS[KING][i][N];

            % If the piece has the same color do not mark the position (and continue),
            % otherwise the piece can be captured and therefore the position must be marked
            % Out of bounds
            if (m < 0 || n < 0 || m >= BOARD_HEIGHT || n >= BOARD_WIDTH ||
                pieceColor == complBoard[m][n][COLOR]
            ) {
                continue;
            }

            % Unless there is an enemy king in the neighborhood of that cell
            var result = true;
            for (var m2 = m - 1; m2 < m + 2; m2++) {
                for (var n2 = n - 1; n2 < n + 2; n2++) {
                    % Out of bounds check
                    if (m2 < 0 || n2 < 0 || m2 >= BOARD_HEIGHT || n2 >= BOARD_WIDTH) {
                        continue;
                    }
                    % Check for enemy king
                    if (complBoard[m2][n2][PIECE] == PIECE_SYMBOLS[KING] &&
                        complBoard[m2][n2][COLOR] != pieceColor
                    ) {
                         result = false;
                    }
                }
            }
            % If no king in the neighborhood and the cell is not checked -> highlight cell
            if (result && noCheck(m, n, pieceColor)) {
                highlight(m, n, POSS_MOVE_COLOR, enable);
            }
        }

        % Special case: castling
        var pColor = complBoard[lastSelection[M]][lastSelection[N]][COLOR];
        var rookPos = [
            [[7, 0, +1], [7, 7, -1]], % white
            [[], []], % padding
            [[0, 0, +1], [0, 7, -1]] % black
        ];
        % If the king was not moved yet test all his rooks if they are available
        % for castling
        if (complBoard[lastSelection[M]][lastSelection[N]][MOVES] == 0 && !check) {
            % Iterate rook positions
            for (var i = 0; i < rookPos[pColor + 1].length; i++) {
                var pos = rookPos[pColor + 1][i];
                % If the rook is of the right color and also was not yet moved
                if (complBoard[pos[M]][pos[N]][PIECE] == PIECE_SYMBOLS[ROOK] &&
                    complBoard[pos[M]][pos[N]][MOVES] == 0
                ) {
                    var res = true;
                    var nHPos = Math.round((pos[N] + lastSelection[N]) * 0.5);
                    % Check if cells in between are empty
                    for (var n = pos[N] + pos[2]; n != lastSelection[N]; n += pos[2]) {
                        res &= complBoard[pos[M]][n][PIECE] == EMPTY;
                    }
                    % Check if cells are in check
                    for (var n = nHPos; n != lastSelection[N]; n += pos[2]) {
                        res &= noCheck(pos[M], n, pColor);
                    }

                    if (res) {
                        highlight(pos[M],  nHPos, POSS_MOVE_COLOR, enable);
                    }
                }
            }
        }
    }
}

/**
 * Loops over the cells in all given directions for the specified number of steps.
 * The highlight state of all processed cells is adjusted.
 * A cell is not highlighted when the own king would be checked as a result of this move.
 * Furthermore a direction is only processed as long as there was no piece on its path.
 *
 * @param {Array} dirs Direction array with pairs of [M, N].
 * @param {Number} len The number of steps to be taken in each direction.
 * @param {Boolean} enable Disables or enables the highlight.
 */
function loopPositions(dirs, len, enable) {
    % The color of the currently selected piece
    var pieceColor = complBoard[lastSelection[M]][lastSelection[N]][COLOR];

    % Iterate all directions of this piece
    for (var i = 0; i < dirs.length; i++) {
        for (var o = 1; o < len; o++) {

            var m = lastSelection[M] + o * dirs[i][M];
            var n = lastSelection[N] + o * dirs[i][N];

            % If the piece has the same color do not mark the position (and break),
            % otherwise the piece can be captured and therefore the position must be marked
            % Out of bounds check
            if (m < 0 || n < 0 || m >= BOARD_HEIGHT || n >= BOARD_WIDTH ||
                pieceColor == complBoard[m][n][COLOR]
            ) {
                break;
            }
            % Moves are only allowed if the own king is not checked afterwards
            if (noCheck(m, n, pieceColor)) {
                highlight(m, n, POSS_MOVE_COLOR, enable);
            }
            % Break when the way is shut
            if (complBoard[m][n][PIECE] != EMPTY) {
                break;
            }
        }
    }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Check, noCheck, checkmate and pawn promotion test %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/**
 * Test if the king of the given color is checked.
 * Starting from the king position each possible direction is iterated.
 * If an enemy piece is found that would be able to capture the king, he is checked.
 * The knight positions are processed independently since they have a special move pattern.
 *
 * @param {Number} col The color of the king that is to be checked.
 * @return {Boolean} True if the king is checked, false otherwise.
 */
function testCheck(col) {
    % Check in all directions if there is an enemy piece
    % in that case check whether it would be able to capture the king
    for (var i = 0; i < DIRS[KING].length; i++) {
        % Iterate as far as possible
        for (var o = 1; o < Math.max(BOARD_WIDTH, BOARD_HEIGHT); o++) {
            % Get the king position + the direction vector
            var m = kingPos[col + 1][M] + o * DIRS[KING][i][M];
            var n = kingPos[col + 1][N] + o * DIRS[KING][i][N];

            % If the piece has the same color do nothing
            % Out of bounds check
            if (m < 0 || n < 0 || m >= BOARD_HEIGHT || n >= BOARD_WIDTH ||
                col == complBoard[m][n][COLOR]
            ) {
                break;
            }
            % Otherwise the king might be attacked
            if (complBoard[m][n][PIECE] != EMPTY) {
                % If indeed the king is attacked mark his position
                if (complBoard[m][n][PIECE] == PIECE_SYMBOLS[QUEEN] ||
                    (complBoard[m][n][PIECE] == PIECE_SYMBOLS[BISHOP] && (i \% 2 == 1)) ||
                    (complBoard[m][n][PIECE] == PIECE_SYMBOLS[ROOK] && (i \% 2 == 0)) ||
                    (complBoard[m][n][PIECE] == PIECE_SYMBOLS[PAWN] &&
                        o == 1 && m + col * -1 == kingPos[col + 1][M] && (i \% 2 == 1))
                ) {
                    return true;
                }
                break;
            }
        }
    }

    % Special case: knight positions
    for (var i = 0; i < DIRS[KNIGHT].length; i++) {
        var m = kingPos[col + 1][M] + DIRS[KNIGHT][i][M];
        var n = kingPos[col + 1][N] + DIRS[KNIGHT][i][N];

        % If the piece has the same color do nothing
        % Out of bounds check
        if (m < 0 || n < 0 || m >= BOARD_HEIGHT || n >= BOARD_WIDTH ||
            col == complBoard[m][n][COLOR]
        ) {
            continue;
        }

        % Otherwise the king is attacked
        if (complBoard[m][n][PIECE] == PIECE_SYMBOLS[KNIGHT]) {
            return true;
        }
    }

    return false;
}

/**
 * Iterates all cells. If a cell contains a piece that has the currentTurn color
 * its valid moves are calculated. As soon as there is a valid move of any piece
 * found it is known that the game is not over, since the player could make this move.
 *
 * @return {Boolean} True if the game is over and no move was found, false otherwise.
 */
function testGameover() {
    % Reset count
    highlightCount = 0;
    % Since it is unknown where the pieces are iterate all cells
    for (var m = 0; m < BOARD_HEIGHT; m++) {
        for (var n = 0; n < BOARD_WIDTH; n++) {
            % Select the pieces with the currentTurn color
            if (currentTurn == complBoard[m][n][COLOR]) {
                lastSelection = [m, n];
                % Count possible moves
                highlightValidMoves(false);
                % A move was found, therefore the game is not yet over
                if (highlightCount > 0) {
                    lastSelection = [];
                    return false;
                }
            }
        }
    }
    % No move was found, the game must be over
    return true;
}

/**
 * Checks if a move would result in checking the king, by actually playing the move
 * and reverting it afterwards.
 *
 * @param {Number} m The m position (height).
 * @param {Number} n The n position (width).
 * @param {Number} color The color of the king to check.
 * @return {Boolen} True if the king is not checked, false otherwise.
 */
function noCheck(m, n, color) {
    var result = true;

    % If the selected piece is the king adjust his position
    var isKing = complBoard[lastSelection[M]][lastSelection[N]][PIECE] == PIECE_SYMBOLS[KING];
    if (isKing) {
        kingPos[color + 1] = [m, n];
    }

    % Set the piece to the given position
    var tmp = complBoard[m][n];
    complBoard[m][n] = complBoard[lastSelection[M]][lastSelection[N]];
    complBoard[lastSelection[M]][lastSelection[N]] = [EMPTY, NONE, UNMOVED];

    % If the players king does not end up checked allow move
    result = !testCheck(color);

    % If the selected piece was the king reset his position
    if (isKing) {
        kingPos[color + 1] = [lastSelection[M], lastSelection[N]];
    }

    % Reset the piece to its origin
    complBoard[lastSelection[M]][lastSelection[N]] = complBoard[m][n];
    complBoard[m][n] = tmp;

    return result;
}

/**
 * This function is called after pressing one promotion button (GUI).
 * If there is a pawn to promote, the selection decides to what piece he is promoted.
 * @param {Number} sel The id of the promotion button (0-3).
 */
function promotePawn(sel) {
    % Check if there is something to promote
    if (promotionPos.length > 0) {
        % Change the piece to the selection
        complBoard[promotionPos[M]][promotionPos[N]][PIECE] = PIECE_SYMBOLS[QUEEN + sel];
        draw(promotionPos[M], promotionPos[N]);
        promotionPos = [];
        % Hide the buttons
        showPromotionButtons(false);
        printInfoText("Pawn promoted to " + PIECE_SYMBOLS[QUEEN + sel] + ".");
    }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Process positional input %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/**
 * Process all moves that are given via the moves-field.
 * These moves should be of PGN format.
 * Multiple PGN examples where used to validate the correctness of
 * the function. These can be found here:
 * https://en.wikipedia.org/wiki/Portable_Game_Notation
 */
function processMoves() {
    this.getField("info").setFocus();
    % Prevent applying input to a finished game
    if (checkmate || stalemate) {
        printInfoText("Game over, please restart the game!");
        return;
    }

    % Get the input string
    var input = this.getField("moves").value;
    % Remove comments from input
    input = input.replace(/ *\{[^\}]*\}*/g, "");
    % Split the turns using the turn-number
    var allTurns = input.split(/\s*\d+\.\s*|,\s*/);

    % Remove empty string when splitting numbered list
    if (input.indexOf('.') > -1) {
        allTurns.splice(0, 1);
    }

    % Add both parts of a turn to the moves array
    movesToProcess = [];
    for (var idx = 0; idx < allTurns.length; idx++) {
        var parts = allTurns[idx].split(" ");
        for (var j = 0; j < parts.length; j++) {
            movesToProcess.push(parts[j]);
        }
    }

    printInfoText("Start interval and move processing.");
    playInterval = app.setInterval("processNextMove();", PLAYBACK_SPEED);
}

/**
 * Processes the move at position 0 from the movesToProcess array until the array is empty.
 * Each move has two states, first being shown on the board and then being executed.
 * The 0 element of the array is removed after the processing finishes.
 */
function processNextMove() {
    if (movesToProcess.length == 0) {
        printInfoText("All moves were processed.");
        app.clearInterval(playInterval);
        return;
    }

    % Test whether the move should be applied or shown
    if (processBool) {
        % Convert the move to a src and tgt position and save it for the next step
        conversion = convert(movesToProcess[0]);
        % If the conversion does not have a src and a tgt position, either
        % the game is over or the move is faulty
        if (conversion.length != 2) {
            if (conversion.length == 1) {
                printInfoText("Game over, " + conversion[0] + " won.");
            } else {
                printInfoText("Could not find a valid move for " + movesToProcess[0] + ".");
            }
            % Remove unprocessed elements
            movesToProcess.length = 0
            app.clearInterval(playInterval);
            return;
        }
        move(conversion[0][M], conversion[0][N]);
    } else {
        move(conversion[1][M], conversion[1][N]);
        % Test for promotion
        if (promotionPos.length > 0) {
            promotePawn(promotionIndex);
        }
        % Remove the processed move
        movesToProcess.splice(0, 1);
    }

    printInfoText("Moving: " + conversion[0] + " to " + conversion[1] +
        ". Remaining: " + movesToProcess);
    processBool = !processBool;
}

/**
 * This function is able to parse PGN notation.
 * These inputs can be processed:
 * - castles O-O and O-O-O
 * - pawn movements -> cb5
 * - other piece movements -> Nbd7
 * - pawn promotion -> e8=Q#
 * - result info -> 1/2-1/2, 0-1, 1-0
 * These move information are ignored by removing the symbols:
 * - captures -> x
 * - check -> +
 * - checkmate -> #
 * - moveinfo -> ! and ?
 *
 * Using the PGN notation the input is converted into the local coordinate system
 * with m and n coordinates for the target and the source.
 *
 * @param {Array} curTurn A single turn of the input that shall be converted.
 * @return {Array} The converted position in form of src and tgt position.
 */
function convert(curTurn) {
    var result = [];
    var piece = "P";

    var tgtM = -1;
    var tgtN = -1;
    var srcM = -1;
    var srcN = -1;

    % Delete all additional symbols that are not necessary to move the piece
    var turnClean = curTurn.replace(/x|\+|#|!|\?/g, "");

    % Game over, white won
    if (turnClean == "1-0") {
        checkmate = true;
        return ["White"];
    }
    % Game over, black won
    else if (turnClean == "0-1") {
        checkmate = true;
        return ["Black"];
    }
    % Game over, noone won
    else if (turnClean == "1\/2-1\/2") {
        stalemate = true;
        return ["No one"];
    }
    % King side castles
    else if (turnClean == "O-O") {
        tgtM = currentTurn == WHITE ? 7 : 0;
        tgtN = 6;
        piece = "K";
    }
    % Queen side castles
    else if (turnClean == "O-O-O") {
        tgtM = currentTurn == WHITE ? 7 : 0;
        tgtN = 2;
        piece = "K";
    } else {
        var characters = turnClean.split("");
        % Get the piece that should be moved
        if (characters.length == 2) {
            % piece = "P";
        } else if (characters[0].charCodeAt(0) - 90 > 0) {
            % piece = "P";
            % Pawn promotion
            if (characters[characters.length - 2] == "=") {
                var promotionChar = characters[characters.length - 1];
                if (promotionChar == "Q") {
                    promotionIndex = 0;
                } else if (promotionChar == "B") {
                    promotionIndex = 1;
                } else if (promotionChar == "N") {
                    promotionIndex = 2;
                } else {
                    promotionIndex = 3;
                }
                characters.splice(characters.length - 2);
            }
        } else {
            piece = characters[0];
            characters.splice(0, 1);
        }

        % Get the target position
        var tgtM = 8 - parseInt(characters[characters.length - 1], 10);
        var tgtN = characters[characters.length - 2].charCodeAt(0) - 97;

        % Check if there are additional movement information
        for (var charPos = 0; charPos <= characters.length - 3; charPos++) {
            var column = characters[charPos].charCodeAt(0) - 97;
            if (column >= 0) {
                srcN = column;
            } else {
                srcM = 8 - parseInt(characters[charPos], 10);
            }
        }
    }

    % Only allow letters a-h and only numbers from 1-8
    if (tgtM < 0 || tgtN < 0 || tgtM >= BOARD_HEIGHT || tgtN >= BOARD_WIDTH ||
        srcM >= BOARD_HEIGHT || srcN >= BOARD_WIDTH
    ) {
        return [];
    }

    % After validating the target position the source position must be obtained
    var srcPos = getSourcePosition(tgtM, tgtN, srcM, srcN, piece);
    if (srcPos.length != 2) {
        return [];
    } else {
        % Return the source and target positions
        result.push(srcPos);
        result.push([tgtM, tgtN]);
    }

    return result;
}

/**
 * Iterates all cells and checks whether the cell-piece matches the piece that is given
 * and has the same color as the currentTurn.
 * Each time a valid piece is found its moves are highlighted and validMove is called to
 * validate if the move is possible. If the move is possible the piece position is returned
 * to be used as source position. All highlights are disabled after each test.
 * Should it not be possible to find a matching piece an empty array is returned.
 * Additionally the source row or column can be specified to limit the search radius.
 *
 * @param {Number} tgtM The target row index.
 * @param {Number} tgtN The target column index.
 * @param {Number} srcM The source row index, use 0 is no row is known.
 * @param {Number} srcN The source column index, use 0 is no row is known.
 * @param {String} piece The search piece character.
 */
function getSourcePosition(tgtM, tgtN, srcM, srcN, piece) {
    for (var m = 0; m < BOARD_HEIGHT; m++) {
        % If a row is given only check this one row
        if (srcM > -1 && m != srcM) {
            continue;
        }

        for (var n = 0; n < BOARD_WIDTH; n++) {
            % If a column is given only check this one column
            if (srcN > -1 && n != srcN) {
                continue;
            }

            % Select the pieces with the currentTurn color
            if (currentTurn == complBoard[m][n][COLOR] && piece == complBoard[m][n][PIECE]) {

                lastSelection = [m, n];
                % Mark all cells that are accessible
                highlightValidMoves(true);

                if (validMove(tgtM, tgtN)) {
                    % Disable highlight
                    highlightValidMoves(false);
                    lastSelection = [];
                    return [m, n];
                }

                % Disable highlight
                highlightValidMoves(false);
            }
        }
    }
    % Reset selection
    lastSelection = [];
    return [];
}

%%%%%%%%%%%%%%%%%%%%%
% Draw and coloring %
%%%%%%%%%%%%%%%%%%%%%
/**
 * Draws the complete board.
 */
function drawAll() {
    for (var m = 0; m < BOARD_HEIGHT; m++) {
        for (var n = 0; n < BOARD_WIDTH; n++) {
            draw(m, n);
        }
    }
}

/**
 * Draw the cell at the coordinates m, n.
 *
 * @param {Number} m The m position (height).
 * @param {Number} n The n position (width).
 */
function draw(m, n) {
    % Retrieve the cell data
    var cell = this.getField("cell" + m + "-" + n);
    cell.delay = true;

    cell.value = complBoard[m][n][PIECE];

    % Adjust piece color dependent on its owner
    if (complBoard[m][n][COLOR] == WHITE) {
        cell.textColor = TEXT_COLORS[WHITE + 1];
    } else if (complBoard[m][n][COLOR] == BLACK) {
        cell.textColor = TEXT_COLORS[BLACK];
    }

    % Adjust bordcolor
    if ((m + n) \% 2 == 0) {
        cell.borderColor = CELL_COLORS[WHITE + 1];
        cell.fillColor = CELL_COLORS[WHITE + 1];
    } else {
        cell.borderColor = CELL_COLORS[BLACK];
        cell.fillColor = CELL_COLORS[BLACK];
    }

    cell.delay = false;
}

/**
 *
 * @param {Number} m The m position (height).
 * @param {Number} n The n position (width).
 * @param {Array} color The color with which to highlight.
 * @param {Boolean} enable True to enable, false to disable.
 */
function highlight(m, n, color, enable) {
    var cell = this.getField("cell" + m + "-" + n);
    cell.delay = true;

    % Indicator for how often this function was called
    % This is used to check if there are any possible moves
    highlightCount++;

    if (enable) {
        cell.borderColor = color;
    } else {
        cell.borderColor = cell.fillColor;
    }
    cell.delay = false;
}

/**
 * Show or hide the buttons for the promotion selection.
 * @param {Boolean} show True to show the buttons, false to hide them.
 */
function showPromotionButtons(show) {
    for (var i = 0; i < 4; i++) {
        var cell = this.getField("promote" + i);
        cell.hidden = !show;
    }
}

/**
 * Print information about the winner and the gamestate.
 */
function printInfoText(text) {
    var field = this.getField("info");
    field.delay = true;
    field.value = text;
    field.delay = false;
}

\end{insDLJS}

\OpenAction{/S /JavaScript /JS (initialise();)}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Dokument
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}

    \begin{Form}

        % Header
        \begin{multicols}{2}
            % Title
            \section*{Chess}
        \columnbreak
            % Tooltip object
            \begin{flushright}%
                \PushButton[name=tooltipbtn, bordercolor=white]{%
                    \begin{tcolorbox}[width=20pt, height=20pt, left=3pt, top=0pt]
                        \centering?\strut{}
                    \end{tcolorbox}%
                }
            \end{flushright}%
        \end{multicols}

        % Calculate the max width and height of a block
        \FPeval{\resultW}{(\boardWidth * 4 + 3)}
        \def\blocksizeW{\dimexpr (\linewidth-\resultW pt)/\boardWidth \relax}

        \FPeval{\resultH}{(\boardHeight * 4 + 3)}
        \def\blocksizeH{\dimexpr (500 pt -\resultH pt)/\boardHeight \relax}

        % Define the blocksize via the smaller amount
        \ifnum\blocksizeW<\blocksizeH
            \def\blocksize{\blocksizeW}
        \else
            \def\blocksize{\blocksizeH}
        \fi

        % The game board
        \begin{tcolorbox}
            \begin{flushright}
                \xintFor* #1 in {\xintSeq{0}{\boardHeight-1}} \do {%
                    \xintFor* #2 in {\xintSeq{0}{\boardWidth-1}} \do {%
                        \TextField[%
                            width=\blocksize, height=\blocksize,%
                            bordercolor=white, name=cell#1-#2, readonly=true]{}\hspace{3pt}%
                    }\vspace{3pt}
                    \newline%
                }%
            \end{flushright}%
        \end{tcolorbox}

        % Game related buttons
        \begin{center}%
            % Pawn promotion buttons
            \begin{tabularx}{\textwidth}{@{} *{4}{X} @{}}%
                \xintFor* #1 in {\xintSeq{0}{3}} \do {%
                    \begin{tcolorbox}
                        \TextField[
                            name=promote#1, width=\linewidth, bordercolor=gray, readonly=true
                        ]{}
                    \end{tcolorbox}
                    % Have the cell divider for all elements
                    % that are not the last one
                    \xintifForLast{}{&}%
                }
            \end{tabularx}

            \begin{tabularx}{\textwidth}{@{} *{2}{X} @{}}%
                \begin{tcolorbox}
                    \TextField[name=moves, bordercolor=gray, width=\linewidth]{}
                \end{tcolorbox} &%
                \PushButton[name=process, bordercolor=white]{
                    \begin{tcolorbox}
                        \centering
                        Process moves
                        \strut
                    \end{tcolorbox}
                }\\
                \PushButton[name=restart, bordercolor=white]{
                    \begin{tcolorbox}
                        \centering
                        Restart
                        \strut
                    \end{tcolorbox}
                } &%
                \begin{tcolorbox}
                    \TextField[name=info, width=\linewidth, readonly=true]{}
                \end{tcolorbox}
            \end{tabularx}
        \end{center}

        \TextField[bordercolor=, name=tooltiptxt, readonly=true, hidden]{}

    \end{Form}

\end{document}


\documentclass{beamer}

\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage[ruled, linesnumbered]{algorithm2e}

\title{Introduction to Multilayer Perceptron}
\subtitle{Multilayer Fully Connected Feedforward Neural Networks}
\author{Vitor Greati\inst{1}}
\institute[]
{
	\inst{1}%
	Federal University of Rio Grande do Norte
}
\date{}
\subject{Computer Science}

% Table of contents at the beginning of each section
\AtBeginSection[]
{
  \begin{frame}
    \frametitle{Table of Contents}
    \tableofcontents[currentsection]
  \end{frame}
}

% Table of contents at the beginning of each subsection
%\AtBeginSubsection[]
%{
%  \begin{frame}
%    \frametitle{Table of Contents}
%    \tableofcontents[currentsection,currentsubsection]
%  \end{frame}
%}

\begin{document}

\frame{\titlepage}

\section{Introduction}

    \subsection{Concept}

         \begin{frame}{Concept}{Defining Neural Networks}

            Neural Networks or Artificial Neural Networks are computational models
            inspired in the neural system, containing a \textbf{labelled directed graph} $G=(V,E)$ whose nodes
            are capable of performing some \textbf{simple computation} and where each edge $(u,v) \in E$ \textbf{carries the output}
            of such computation from $u$ to $v$ increased or diminished by the \textbf{edge weight} $w(u,v)$.\\~\\

The weights
            indicate the importance degree of the signal of each connection.\\~\\

In a Neural Network,
            these \textbf{weights are modified} during the learning process by \textbf{learning algorithms}.

        \end{frame}

    \subsection{Applications}
        \begin{frame}{Applications}{Neural Networks for what?}

            Neural networks can be applied to supervised, unsupervised and semi-supervised learning
            tasks, given the right architecture.\\~\\

            Common applications are:
            \begin{itemize}
                \item classification;
                \item regression;
                \item clustering;
                \item vector quantization;
                \item pattern association;
                \item function approximation.
            \end{itemize}
        \end{frame}

    \subsection{Neurons}
    \begin{frame}{Neurons}{Basic elements}

        The neuron's basic task is to take an input, perform some computation and
        output a value.

        \begin{block}{Main elements}
            \begin{itemize}
                \item An input vector $\mathbf{x} = \langle x_1, x_2, \ldots, x_n \rangle \in \mathbb{R}^n$.
                \item A vector of weights $\mathbf{w} = \langle w_1, w_2, \ldots, w_n \rangle \in \mathbb{R}^n$.
                \item A value $b \in \mathbb{R}$, called \emph{bias}.
                \item A computation between inputs and weights, like
                    $$z=\mathbf{x}\cdot\mathbf{w} =\sum_i x_iw_i.$$
                \item An activation function $f$ to produce an output $f(z + b)$.
            \end{itemize}
        \end{block}
    \end{frame}

    \begin{frame}{Neurons}{Graphical representation}
        A common graphical representation highlights those elements:
        \begin{figure}
            \centering
            \begin{tikzpicture}
                \draw (4,1) node[circle,minimum size=3cm,draw] (A) {};
                \node (B) at (0,3) {$x_1$};
                \node (C) at (0,2) {$x_2$};
                \node (D) at (0,1) {$x_3$};
                \node (E) at (0,0) {$\vdots$};
                \node (F) at (0,-1) {$x_n$};
                \draw [->] (B) -- node [above] {$w_1$} (A);
                \draw [->] (C) -- node [above] {$w_2$}(A);
                \draw [->] (D) -- node [above] {$w_3$}(A);
                \draw [->] (F) -- node [above] {$w_n$}(A);
                \node (H) at (8,1) {$a=f(z+b)$};
                \draw [->] (A) -- (H);
                \node (G) at (4,1) {$z=\sum_i x_iw_i$};
            \end{tikzpicture}
        \end{figure}
    \end{frame}

    \begin{frame}{Neurons}{Graphical representation}
        The same representation, but using only vectors:

        \begin{figure}
            \centering
            \begin{tikzpicture}
                \draw (4,1) node[circle,minimum size=3cm,draw] (A) {};
                \node (D) at (0,1) {$\mathbf x$};
                \draw [->] (D) -- node [above] {$\mathbf w$}(A);
                \node (H) at (8,1) {$a=f(z+b)$};
                \draw [->] (A) -- (H);
                \node (G) at (4,1) {$z=\mathbf{x} \cdot \mathbf{w}$};
            \end{tikzpicture}
        \end{figure}
    \end{frame}

    \subsection{Activation functions}

        \begin{frame}{Activation functions}{Sigmoid function}

            The sigmoid is a classical function in the neuron activation context. It is defined by:

            \begin{displaymath}
                f_{sig}(net) = \frac{1}{1 + e^{-net}}
            \end{displaymath}

            When compared to the step function:
            \begin{itemize}
                \item $f_{sig}$ is continuous and differentiable everywhere;
                \item $f_{sig}$ is symmetric around the y-axis;
                \item $f_{sig}$ asymptotically approaches its saturation values.
            \end{itemize}

            However:
            \begin{itemize}
                \item $f_{sig}$ outputs are not zero centered;
                \item Saturated neurons essentially kill the gradient, since the delta will be extremely small.
            \end{itemize}
        \end{frame}

        \begin{frame}{Activation functions}{Step function}

            The step function is defined as
            \begin{displaymath}
                f_s(net) =
                \begin{cases}
                    1, net > 0\\
                    0, net < 0\\
                \end{cases}
            \end{displaymath}

            Notice that:
            \begin{itemize}
                \item $f_s$ only lets the signal pass if the computation results in a positive net;
                \item $f_s$ is not differentiable, which produce problems for some learning algorithms;
            \end{itemize}

            This activation is used in the classic \textbf{Perceptron}.

        \end{frame}

        \begin{frame}{Activation functions}{Hyperbolic tangent function}

            The hyperbolic tangent function is defined as
            \begin{displaymath}
                f_{tanh}(net) = \tanh(net) = \frac{e^{net} - e^{-net}}{e^{net} + e^{-net}}.
            \end{displaymath}

            Notice that:
            \begin{itemize}
                \item $f_{tanh}$ is zero centered;
                \item The problem for saturated neurons remains.
            \end{itemize}

        \end{frame}

        \begin{frame}{Activation functions}{ReLU - Rectified Linear Unit}

            The ReLU function is defined as:

            \begin{displaymath}
                f_{relu}(net) = \max(0, net).
            \end{displaymath}

            Notice:
            \begin{itemize}
                \item $f_{relu}$ is not saturable and it is extremely efficient;
                \item $f_{relu}$ is not differentiable at $0$.
            \end{itemize}

        \end{frame}

        \begin{frame}{Activation functions}{Leaky ReLU - Leaky Rectified Linear Unit}
            The Leaky ReLU is defined as:

            \begin{displaymath}
                f_{lrelu}(net)=
                \begin{cases}
                    net, net \geq 0\\
                    \alpha \times net, net < 0
                \end{cases}
            \end{displaymath}

            \begin{itemize}
                \item $f_{lrelu}$ allows a small, non-zero gradient at $0$;
                \item $f_{lrelu}$ allows negative values;
                \item PReLUs, Parametric ReLUs, allows $\alpha$ to be learned differently for each node.
            \end{itemize}
        \end{frame}

        \begin{frame}{Activation functions}{ELU - Exponential Linear Units}
            The ELU function is defined as:

            \begin{displaymath}
                f_{elu}(net) =
                \begin{cases}
                    net, net \geq 0\\
                    \alpha \times (e^{net} - 1), neq < 0
                \end{cases}
            \end{displaymath}

            Here, $\alpha$ is a constant, set when the network is instantiated. A common
            value for it is $\alpha = 1.0$.\\~\\

            ELUs have presented better results than ReLUs.

        \end{frame}

\section{Multilayer Perceptron}

    \subsection{Architecture}

        \begin{frame}{Multilayer Architecture}{Fully connected feedforward architecture}

            An architecture with $C$ layers, $L_0, L_1, \ldots, L_{C-1}$,
            is graphically represented as:

            \begin{figure}
                \centering
                \begin{tikzpicture}
                    % Layer 1
                    \draw (0,4) node[circle,minimum size=0.8cm,draw] (A1) {};
                    \draw (0,3) node[circle,minimum size=0.8cm,draw] (A2) {};
                    \draw (0,2) node[circle,minimum size=0.8cm,draw] (A3) {};
                    \node (A) at (0,1) {$\vdots$};
                    \draw (0,0) node[circle,minimum size=0.8cm,draw] (A4) {};
                    \node (AL) at (0,-1) {$L_0$};
                    % Ins
                    \node (I1) at (-1,4) {$x_1$};
                    \draw [->](I1) -- (A1);
                    \node (I2) at (-1,3) {$x_2$};
                    \draw [->](I2) -- (A2);
                    \node (I3) at (-1,2) {$x_3$};
                    \draw [->](I3) -- (A3);
                    \node (I) at (-1,1) {$\vdots$};
                    \node (I4) at (-1,0) {$x_n$};
                    \draw [->](I4) -- (A4);
                    % Layer 2
                    \draw (3,4) node[circle,minimum size=0.8cm,draw] (B1) {};
                    \draw (3,3) node[circle,minimum size=0.8cm,draw] (B2) {};
                    \draw (3,2) node[circle,minimum size=0.8cm,draw] (B3) {};
                    \node (B) at (3,1) {$\vdots$};
                    \draw (3,0) node[circle,minimum size=0.8cm,draw] (B4) {};
                    \node (BL) at (3,-1) {$L_1$};
                    % Layer 3
                    \draw (6,4) node[circle,minimum size=0.8cm,draw] (C1) {};
                    \draw (6,3) node[circle,minimum size=0.8cm,draw] (C2) {};
                    \draw (6,2) node[circle,minimum size=0.8cm,draw] (C3) {};
                    \node (C) at (6,1) {$\vdots$};
                    \draw (6,0) node[circle,minimum size=0.8cm,draw] (C4) {};
                    \node (CL) at (6,-1) {$L_2$};
                    % Layers 4..k-1
                    \node (DDD1) at (7,2) {$\ldots$};
                    \node (DDD2) at (7,-1) {$\ldots$};
                    % Layer k
                    \draw (8,4) node[circle,minimum size=0.8cm,draw] (D1) {};
                    \draw (8,3) node[circle,minimum size=0.8cm,draw] (D2) {};
                    \draw (8,2) node[circle,minimum size=0.8cm,draw] (D3) {};
                    \node (D) at (8,1) {$\vdots$};
                    \draw (8,0) node[circle,minimum size=0.8cm,draw] (D4) {};
                    \node (DL) at (8,-1) {$L_{C-1}$};
                    % Outs
                    \node (O1) at (9,4) {$a_1$};
                    \draw [->](D1) -- (O1);
                    \node (O2) at (9,3) {$a_2$};
                    \draw [->](D2) -- (O2);
                    \node (O3) at (9,2) {$a_3$};
                    \draw [->](D3) -- (O3);
                    \node (O) at (9,1) {$\vdots$};
                    \node (O4) at (9,0) {$a_{|L_{C-1}|}$};
                    \draw [->](D4) -- (O4);
                    % Links
                    \draw [->] (A1)--(B1);
                    \draw [->] (A1)--(B2);
                    \draw [->] (A1)--(B3);
                    \draw [->] (A1)--(B4);
                    \draw [->] (A1)--(B);
                    \draw [->] (A2)--(B1);
                    \draw [->] (A2)--(B2);
                    \draw [->] (A2)--(B3);
                    \draw [->] (A2)--(B4);
                    \draw [->] (A2)--(B);
                    \draw [->] (A3)--(B1);
                    \draw [->] (A3)--(B2);
                    \draw [->] (A3)--(B3);
                    \draw [->] (A3)--(B4);
                    \draw [->] (A3)--(B);
                    \draw [->] (A4)--(B1);
                    \draw [->] (A4)--(B2);
                    \draw [->] (A4)--(B3);
                    \draw [->] (A4)--(B4);
                    \draw [->] (A4)--(B);
                    \draw [->] (B1)--(C1);
                    \draw [->] (B1)--(C2);
                    \draw [->] (B1)--(C3);
                    \draw [->] (B1)--(C4);
                    \draw [->] (B1)--(C);
                    \draw [->] (B2)--(C1);
                    \draw [->] (B2)--(C2);
                    \draw [->] (B2)--(C3);
                    \draw [->] (B2)--(C4);
                    \draw [->] (B2)--(C);
                    \draw [->] (B3)--(C1);
                    \draw [->] (B3)--(C2);
                    \draw [->] (B3)--(C3);
                    \draw [->] (B3)--(C4);
                    \draw [->] (B3)--(C);
                    \draw [->] (B4)--(C1);
                    \draw [->] (B4)--(C2);
                    \draw [->] (B4)--(C3);
                    \draw [->] (B4)--(C4);
                    \draw [->] (B4)--(C);
                \end{tikzpicture}
            \end{figure}
        \end{frame}

        \begin{frame}{Multilayer Architecture}{Fully connected feedforward architecture}
            \begin{block}{Observations}
                \begin{itemize}
                    \item A layer $L_i$ has its own size (number of neurons) $|L_i|$.
                    \item $L_0$ is the \textbf{input layer}.
                        \begin{itemize}
                            \item Neurons in this layer are \textbf{input neurons}.
                            \item An input neuron $j$ takes the $j$-th component of the input vector.
                            \item Input neurons do not perform any computation or
                                        activation: just output the input value.
                            \item The output of $L_0$ is $\mathbf{x}$, the input vector.
                        \end{itemize}
                    \item $L_{C-1}$ is the \textbf{output layer} and its output is the
                        network output.
                    \item Any other layer is a \textbf{hidden layer}.
                    \item This architecture is \textbf{fully connected} because each neuron in
                        layer $L_i$ is connected to every neuron in layer $L_{i+1}$.
                    \item This architecture is \textbf{feedforward} because there is no back
                        arrows forming cycles; otherwise, it would be \emph{recurrent}.
                \end{itemize}
            \end{block}
        \end{frame}

    \subsection{Mathematical representation}
        \begin{frame}{Multilayer Architecture}{Fully connected feedforward architecture}
            How can we perform calculations and learning in this architecture? Mathematics, of course.

            \begin{block}{Representing connections between layers}
                Consider layer $L_l, l = 1, \ldots, C-1$, and neuron $k$
                of $L_l$. Since the architecture is fully connected,
                $k$ is connected to all neurons $j$ in $L_{l-1}$.
                Denote by $w^l_{kj}$ the weight of the connection
                between neuron $j$ of $L_{l-1}$ and neuron $k$ of $L_l$:

                \begin{figure}
                    \centering
                    \begin{tikzpicture}
                        % Layer l-1
                        \draw (0,4) node[circle,minimum size=0.2cm,draw] (A1) {};
                        %\draw (0,3.5) node[circle,minimum size=0.2cm,draw] (A2) {};
                        \node (A) at (0,3.5) {$\tiny \vdots$};
                        \draw (0,3) node[circle,minimum size=0.2cm,draw] (A3) {};
                        \node (A) at (0,2.5) {$\tiny \vdots$};
                        \draw (0,2) node[circle,minimum size=0.2cm,draw] (A4) {};
                        \node (TLM1) at (0,3) {\tiny j};
                        \node (AL) at (0,1.5) {$L_{l-1}$};
                        % Layer l
                        \draw (2,4) node[circle,minimum size=0.2cm,draw] (A1) {};
                        %\draw (2,3.5) node[circle,minimum size=0.2cm,draw] (A2) {};
                        \draw (2,3) node[circle,minimum size=0.2cm,draw] (A3) {};
                        \node (A) at (2,3.5) {\tiny $\vdots$};
                        \node (TL1) at (2,3) {\tiny k};
                        \node (A) at (2,2.5) {\tiny $\vdots$};
                        \draw (2,2) node[circle,minimum size=0.2cm,draw] (A4) {};
                        \node (AL) at (2,1.5) {$L_{l}$};
                        % link
                        \draw [->] (TLM1) -- node [above] {\tiny $w^l_{kj}$} (TL1);
                    \end{tikzpicture}
                \end{figure}

            \end{block}

        \end{frame}

        \begin{frame}{Multilayer Architecture}{Fully connected feedforward architecture}
                In this way, we can represent all weights between two layers
                using only one matrix $\mathbf{W}^l = (w^l_{kj})$:

                \[
                    \mathbf{W}^l =
                    \begin{bmatrix}
                        w^l_{11} & w^l_{12} & \ldots & w^l_{1|L_{l-1}|}\\
                        w^l_{21} & w^l_{22} & \ldots & w^l_{2|L_{l-1}|}\\
                        \vdots & \vdots & \ddots & \vdots\\
                        w^l_{|L_l|1} & w^l_{|L_l|2} & \ldots & w^l_{|L_l||L_{l-1}|}\\
                    \end{bmatrix}.
                \]

                Notice that:
                \begin{itemize}
                    \item $\mathbf{W}^l$ has dimensions $|L_l| \times |L_{l-1}|$.
                    \item The weight vector of connections to neuron $k$ in $L_l$ is the $k$-th row of $\mathbf{W}^l$, denoted by $\mathbf{w^l_k}$.
                    \item All connections in the network are represented! They are all in matrices $\mathbf{W}^1, \mathbf{W}^2, \ldots, \mathbf{W}^{C-1}$.
                \end{itemize}
        \end{frame}

        \begin{frame}{Multilayer Architecture}{Fully connected feedforward architecture}
            \begin{block}{Representing the biases}
                Remember that each neuron has its own bias. So, let $b^l_k$ denote the
                bias of neuron $k$ in layer $L_l$. Then, the biases in layer $l$ are
                represented as just a vector

                $$\mathbf{b}^l = \langle b^l_1, b^l_2, \ldots, b^l_{|L_{l}|} \rangle.$$

                In this way, all biases are represented by vectors $\mathbf{b}^1, \mathbf{b}^2, \ldots, \mathbf{b}^{C-1}.$
            \end{block}
        \end{frame}

        \begin{frame}{Multilayer Architecture}{Fully connected feedforward architecture}
            \begin{block}{Representing layer outputs}
                Denote by $a^l_k$ the output of neuron $k$ in layer $L_l$, and by $\mathbf{a^l}$ the output vector
                for layer $L_l$. How to compute such output? First, look: \\~\\

                \begin{figure}
                    \centering
                    \begin{tikzpicture}
                        % Layer l-1
                        \draw (0,4) node[circle,minimum size=0.2cm,draw] (A1) {};
                        \draw (0,3) node[circle,minimum size=0.2cm,draw] (A2) {};
                        \draw (0,2) node[circle,minimum size=0.2cm,draw] (A3) {};
                        \node (A) at (0,1.5) {$\tiny \vdots$};
                        \draw (0,0.5) node[circle,minimum size=0.2cm,draw] (A4) {};
                        \node (BL) at (0,0) {$L_{l-1}$};
                        % Layer l
                        \draw (2,4) node[circle,minimum size=0.2cm,draw] (B1) {};
                        %\draw (2,3.5) node[circle,minimum size=0.2cm,draw] (A2) {};
                        \draw (2,3) node[circle,minimum size=0.2cm,draw] (B3) {};
                        \node (A) at (2,3.5) {\tiny $\vdots$};
                        \node (TL1) at (2,3) {\tiny k};
                        \node (B) at (2,2.5) {\tiny $\vdots$};
                        \draw (2,2) node[circle,minimum size=0.2cm,draw] (B4) {};
                        \node (AL) at (2,1.5) {$L_{l}$};
                        % link
                        \draw [->] (A1) node [above] {\hspace{0.8cm} \tiny $a^{l-1}_1$} -- node [above] {\tiny $w^l_{k1}$} (B3);
                        \draw [->] (A2)  node [above] {\hspace{0.8cm} \tiny $a^{l-1}_2$}-- node [above] {\tiny $w^l_{k2}$} (B3);
                        \draw [->] (A3)  node [above] {\hspace{0.6cm} \tiny $a^{l-1}_3$}-- node [above] {\tiny $w^l_{k3}$} (TL1);
                        \draw [->] (A4)  node [above] {\hspace{1.5cm} \tiny $a^{l-1}_{|L_{l-1}|}$}-- node [below] {\hspace{.6cm}\tiny $w^l_{k|L_{l-1}|}$} (B3);
                        % outs
                        \node (O1) at (3,3) {\tiny $a^l_k$};
                        \draw [->](TL1) -- (O1);

                    \end{tikzpicture}
                \end{figure}
            \end{block}
        \end{frame}

        \begin{frame}{Multilayer Architecture}{Fully connected feedforward architecture}
                Denote by $z^l_k$
                the computation performed by the neuron, i.e:
                \[
                    z^l_k = \sum_j^{|L_{l-1}|} w^l_{kj}a^{l-1}_{j} = \mathbf{w^l_k}\mathbf{a^{l-1}}.
                \]
                Then, the neuron output is
                \[
                    a^l_k = f(z^l_k + b^l_k).
                \]
                And the \textbf{layer output} is
                \[
                    \mathbf{a}^l = \mathbf{f}(\mathbf{W}^l \cdot \mathbf{a}^{l-1} + \mathbf{b}^l).
                \]
        \end{frame}

        \begin{frame}{Multilayer Architecture}{Fully connected feedforward architecture}
                Didn't get it? Look:

                {\tiny
                \begin{align*}
                    \mathbf{f}\left( \mathbf{W}^l \cdot \mathbf{a^{l-1}} + \mathbf{b^l} \right) &=
                    \mathbf{f} \left( \begin{bmatrix}
                        w^l_{11} & w^l_{12} & \ldots & w^l_{1|L_{l-1}|}\\
                        w^l_{21} & w^l_{22} & \ldots & w^l_{2|L_{l-1}|}\\
                        \vdots & \vdots & \ddots & \vdots\\
                        w^l_{|L_l|1} & w^l_{|L_l|2} & \ldots & w^l_{|L_l||L_{l-1}|}\\
                    \end{bmatrix}
                    \cdot
                    \begin{bmatrix}
                        a^{l-1}_1 \\ a^{l-1}_2  \\ \vdots  \\ a^{l-1}_{|L_{l-1}|}
                    \end{bmatrix}
                    +
                    \begin{bmatrix}
                        b^{l}_1 \\ b^{l}_2  \\ \vdots  \\ b^{l}_{|L_l|}
                    \end{bmatrix}
                    \right)\\
                    & =
                    \mathbf{f}\left( \begin{bmatrix}
                        \sum_j^{|L_{l-1}|} w_{1j}a^{l-1}_j + b^l_1\\
                        \sum_j^{|L_{l-1}|} w_{2j}a^{l-1}_j + b^l_2\\
                        \vdots\\
                        \sum_j^{|L_{l-1}|} w_{|L_l|j}a^{l-1}_j + b^l_{|L_l|}\\
                    \end{bmatrix} \right)\\
                    & =
                    \mathbf{f} \left( \begin{bmatrix}
                        \mathbf{w^l_1}\mathbf{a^{l-1}} + b^l_1\\
                        \mathbf{w^l_2}\mathbf{a^{l-1}} + b^l_2\\
                        \vdots\\
                        \mathbf{w^l_{|L_l|}}\mathbf{a^{l-1}} + b^l_{|L_l|}\\
                    \end{bmatrix}\right)\\
                    & =
                    \begin{bmatrix}
                        f(z^l_1) &
                        f(z^l_2) &
                        \ldots &
                        f(z^l_{|L_l|})
                    \end{bmatrix}^T\\
                    & =
                    \begin{bmatrix}
                        a^l_1 &
                        a^l_2 &
                        \ldots &
                        a^l_{|L_l|}
                    \end{bmatrix}^T\\
                    & =
                    \mathbf{a^l}
                \end{align*}
                }
        \end{frame}

    \subsection{Output computation}
        \begin{frame}{Multilayer Architecture}{Computing the network output}
            Given an input vector $\mathbf{x}$, how to compute the output of the network?\\~\\
            We have an equation to compute any $\mathbf{a}^l$ and the algorithm just goes like this:

            \begin{algorithm}[H]
                \KwIn{Input vector $\mathbf{x}$}
                \KwOut{Network output $\mathbf{a}^{C-1}$}
                \Begin{
                    $\mathbf{a}^0 \gets \mathbf{x}$\\
                    \For{$l \gets 1$ \KwTo $C-1$}{
                        $\mathbf{a}^l \gets \mathbf{W}^l \cdot \mathbf{a}^{l-1} + \mathbf{b}^l$
                    }
                    \Return{ $\mathbf{a}^{C-1}$}
                }
            \end{algorithm}
        \end{frame}

\end{document}


\section{New Keynesian Phillips curve}


%File: RBM.tex
%Date: Tue Dec 31 03:29:37 2013 +0800
%Author: Yuxin Wu <ppwwyyxxc@gmail.com>

\subsection{CRBM}

\begin{frame}{CRBM}
  \begin{reference}{4mm}{85mm}
Chen, Hsin and Murray, Alan F, 2003,
Continuous restricted Boltzmann machine with an implementable training algorithm
  \end{reference}
  \begin{itemize}
    \item \textbf{Restricted Boltzmann Machine} is a generative stochastic two-layer neural network.

    \item \textbf{Continuous RBM} extends RBM to real-valued inputs.
      \pause
    \item RBM has the ability to reconstruct a layer similar to input layer.
      The difference between the two layers can be a used to measure the fitness of an input to the model.

    \item Therefore, RBM can be a substituion to GMM.
  \end{itemize}

  \begin{center}
    \visible<2>{\includegraphics[width=0.4\textwidth]{res/rbm-original.png}}
    \visible<2>{\includegraphics[width=0.4\textwidth]{res/rbm-reconstruct.png}}
  \end{center}
  \vspace{1em}
\end{frame}

\begin{frame}{RBM Results}
  Results of CRBM, tested with 5 secs
  of utterance.
  \begin{center}
    \includegraphics[width=0.7\textwidth]{res/crbm.pdf}
  \end{center}
\end{frame}


\subsection{Enumeration fields}
\label{subsec:library_of_transformations:type_level_transformations:enum_fields}

\begin{figure}
    \centering
    \begin{subfigure}{0.45\textwidth}
        \centering
        \includegraphics{images/05_library_of_transformations/02_type_level_transformations/07_enum_fields/enum_field.pdf}
        \caption{$Tm_{EnumField}$ for $.\type{ExistingEnum}$ \\with $name = \type{field}$}
        \label{fig:library_of_transformations:type_level_transformations:enum_fields:visualisation:ecore}
    \end{subfigure}
    \begin{subfigure}{0.45\textwidth}
        \centering
        \input{images/05_library_of_transformations/02_type_level_transformations/07_enum_fields/enum_as_flags_field_as_edge_type.tikz}
        \caption{$TG_{EnumFieldFlags}$ for $\type{ExistingEnum}$ \\with $name = \type{field}$}
        \label{fig:library_of_transformations:type_level_transformations:enum_fields:visualisation:groove_flags}
    \end{subfigure}
    \\
    \begin{subfigure}{0.95\textwidth}
        \centering
        \input{images/05_library_of_transformations/02_type_level_transformations/07_enum_fields/enum_as_node_types_field_as_edge_type.tikz}
        \caption{$TG_{EnumFieldNodes}$ for $\type{ExistingEnum}$ with $name = \type{field}$}
        \label{fig:library_of_transformations:type_level_transformations:enum_fields:visualisation:groove_nodes}
    \end{subfigure}
    \caption{Visualisation of the transformation of a field typed by an enumeration type}
    \label{fig:library_of_transformations:type_level_transformations:enum_fields:visualisation}
\end{figure}

In this section, the transformation for a field typed by an enumeration type will be discussed. Since an enumeration type can be encoded in multiple ways, multiple encodings will be introduced for fields as well. First, the Ecore type model will be introduced.

\begin{defin}[Type model $Tm_{EnumField}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tmod_enum_field}
Let $Tm_{EnumField}$ be the type model containing a regular class with identifier $classtype$. Furthermore, it defines an enumeration type with identifier $enumid$, and corresponding values as set $enumvalues$. Then $Tm_{EnumField}$ defines a field named $name$ with type $enumid$ on class $classtype$. $Tm_{EnumField}$ is defined as:
\begin{align*}
Class =\ &\{classtype\} \\
Enum =\ &\{enumid\} \\
UserDataType =\ &\{\} \\
Field =\ &\{(classtype, name)\} \\
\mathrm{FieldSig} =\ &\begin{cases}
    (f, (enumid, 1..1)) &\mathrm{if}\ f \in Field_{Tm_{EnumField}}
\end{cases} \\
EnumValue =\ &\{(enumid, v) \mid v \in enumvalues\} \\
Inh =\ &\{\} \\
Prop =\ &\{\} \\
Constant =\ &\{\} \\
\mathrm{ConstType} =\ &\{\}
\end{align*}
\isabellelref{tmod_enum_field}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{defin}

\begin{thm}[Correctness of $Tm_{EnumField}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tmod_enum_field_correct}
$Tm_{EnumField}$ (\cref{defin:library_of_transformations:type_level_transformations:enum_fields:tmod_enum_field}) is a consistent type model in the sense of \cref{defin:formalisations:ecore_formalisation:type_models:type_model_consistency}.
\isabellelref{tmod_enum_field_correct}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{thm}

A visual representation of $Tm_{EnumField}$ with field name $\type{field}$ on class $.\type{Example}$ can be seen in \cref{fig:library_of_transformations:type_level_transformations:enum_fields:visualisation:ecore}. In this example, the field is typed by the $.\type{ExistingEnum}$ enumeration type. The correctness proof of $Tm_{EnumField}$ is more involved, it is not included here for conciseness. It can be found within the validated Isabelle proofs.

In order to make composing transformation functions possible, $Tm_{EnumField}$ should be compatible with the type model it is combined with.

\begin{thm}[Correctness of $\mathrm{combine}(Tm, Tm_{EnumField})$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tmod_enum_field_combine_correct}
Assume a type model $Tm$ that is consistent in the sense of \cref{defin:formalisations:ecore_formalisation:type_models:type_model_consistency}. Then $Tm$ is compatible with $Tm_{EnumField}$ (in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_models:compatibility}) if:
\begin{itemize}
    \item The class type on which the field is defined, $classtype$, is already an existing class in $Tm$;
    \item The enumeration type by which the field is typed, $enumid$, is already an existing enumeration type in $Tm$;
    \item All the values for the enumeration type $enumid$ are already enumeration values for $enumid$ in $Tm$;
    \item The field named $name$ is not already a field on $classtype$ in $Tm$.
\end{itemize}
\isabellelref{tmod_enum_field_combine_correct}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{thm}

\begin{proof}
Use \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_models:tmod_combine_merge_correct}. It is possible to show that all assumptions hold. Now we have shown that $\mathrm{combine}(Tm, Tm_{EnumField})$ is consistent in the sense of \cref{defin:formalisations:ecore_formalisation:type_models:type_model_consistency}.
\end{proof}

The definitions and theorems for defining a field typed by an enumeration type within Ecore are now complete.

\subsubsection{Encoding as edge type to an node type encoded enumeration type}

As mentioned earlier, \cref{subsec:library_of_transformations:type_level_transformations:enumeration_types} defines multiple ways to encode an enumeration type. Each of these encodings needs a specialised field encoding. In principle, the encoding of the fields itself is the same, but since every transformation model needs to be valid on its own, the encodings need to be distinguished.

The first encoding for an enumeration type uses node types to encode the different values. The encoding corresponding to $Tm_{EnumField}$, in the case that the field references an enumeration type encoded as node types, can then be represented as $TG_{EnumFieldNodes}$, defined in the following definition:

\begin{defin}[Type graph $TG_{EnumFieldNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_node_types_field_as_edge_type}
Let $TG_{EnumFieldNodes}$ be the type graph containing a node type which encodes the class type $classtype$.
Furthermore, $TG_{EnumFieldNodes}$ contains an encoded version of enumeration type $enumid$ with values from set $enumvalues$. This enumeration type is encoded using node types, as defined in $TG_{EnumNodes}$ (\cref{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_node_types}). Finally, $TG_{EnumFieldNodes}$ defines an edge type from the encoded $classtype$ named $name$ to the encoded enumeration type $enumid$. $TG_{EnumFieldNodes}$ is defined as:
\begin{align*}
NT =\ &\{\mathrm{ns\_\!to\_\!list}(classtype), \mathrm{ns\_\!to\_\!list}(enumid)\}\ \cup \\&\{ \mathrm{ns\_\!to\_\!list}(enumid) \append \langle v \rangle \mid v \in enumvalues \}\\
ET =\ &\{(\mathrm{ns\_\!to\_\!list}(classtype), \langle name \rangle, \mathrm{ns\_\!to\_\!list}(enumid))\} \\
\!\!\sqsubseteq\ =\ &\{(\mathrm{ns\_\!to\_\!list}(classtype), \mathrm{ns\_\!to\_\!list}(classtype)),\ \\& (\mathrm{ns\_\!to\_\!list}(enumid), \mathrm{ns\_\!to\_\!list}(enumid))\}\ \cup \\&
\{(\mathrm{ns\_\!to\_\!list}(enumid) \append \langle v \rangle, \mathrm{ns\_\!to\_\!list}(enumid) \append \langle v \rangle) \mid v \in enumvalues \}\ \cup \\&
\{(\mathrm{ns\_\!to\_\!list}(enumid) \append \langle v \rangle, \mathrm{ns\_\!to\_\!list}(enumid)) \mid v \in enumvalues \} \\
abs =\ &\{\mathrm{ns\_\!to\_\!list}(enumid)\} \\
\mathrm{mult}(e) =\ &\begin{cases}
    (0..\mstar, 1..1) &\mathrm{if}\ e \in \{(\mathrm{ns\_\!to\_\!list}(classtype), \langle name \rangle, \mathrm{ns\_\!to\_\!list}(enumid))\}
\end{cases} \\
contains =\ &\{\}
\end{align*}
\isabellelref{tg_enum_as_node_types_field_as_edge_type}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{defin}

\begin{thm}[Correctness of $TG_{EnumFieldNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_node_types_field_as_edge_type_correct}
$TG_{EnumFieldNodes}$ (\cref{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_node_types_field_as_edge_type}) is a valid type graph in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}.
\isabellelref{tg_enum_as_node_types_field_as_edge_type_correct}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{thm}

A visual representation of $TG_{EnumFieldNodes}$ with edge name $\type{field}$ on node type $\type{Example}$ can be seen in \cref{fig:library_of_transformations:type_level_transformations:enum_fields:visualisation:groove_nodes}. The field references the encoded enumeration type $\type{ExistingEnum}$ via the abstract type, such that its nodes can reference any of the concrete values. The correctness proof of $TG_{EnumFieldNodes}$ is more involved, it is not included here for conciseness. It can be found within the validated Isabelle proofs.

In order to make composing transformation functions possible, $TG_{EnumFieldNodes}$ should be compatible with the type graph it is combined with.

\begin{thm}[Correctness of $\mathrm{combine}(TG, TG_{EnumFieldNodes})$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_node_types_field_as_edge_type_combine_correct}
Assume a type graph $TG$ that is valid in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}. Then $TG$ is compatible with $TG_{EnumFieldNodes}$ (in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_graphs:compatibility}) if:
\begin{itemize}
    \item The node type of the encoded class type in $TG_{EnumFieldNodes}$ is already an node type in $TG$;
    \item All node types corresponding to the encoding of the enumeration type in $TG_{EnumFieldNodes}$ are already node types in $TG$;
    \item The node type of the encoded class type in $TG_{EnumFieldNodes}$ does not already have an edge type with the same name as the field in $TG$.
\end{itemize}
\isabellelref{tg_enum_as_node_types_field_as_edge_type_combine_correct}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{thm}

\begin{proof}
Use \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_graphs:tg_combine_merge_correct}. It is possible to show that all assumptions hold. Now we have shown that $\mathrm{combine}(TG, TG_{EnumFieldNodes})$ is valid in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}.
\end{proof}

The next definitions define the transformation function from $Tm_{EnumField}$ to $TG_{EnumFieldNodes}$:

\begin{defin}[Transformation function $f_{EnumFieldNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tmod_enum_field_to_tg_enum_as_node_types_field_as_edge_type}
The transformation function $f_{EnumFieldNodes}(Tm)$ is defined as:
\begin{align*}
NT =\ &\{\mathrm{ns\_\!to\_\!list}(t) \mid t \in Class_{Tm} \cup Enum_{Tm}\}\ \cup \\&\{ \mathrm{ns\_\!to\_\!list}(e) \append \langle v \rangle \mid (e, v) \in EnumValue_{Tm} \}\\
ET =\ &\{(\mathrm{ns\_\!to\_\!list}(c), \langle f \rangle, \mathrm{ns\_\!to\_\!list}(e)) \mid (c, f) \in Field_{Tm} \land e \in Enum_{Tm}\} \\
\!\!\sqsubseteq\ =\ &\{(\mathrm{ns\_\!to\_\!list}(x), \mathrm{ns\_\!to\_\!list}(x)) \mid x \in Class_{Tm} \cup Enum_{Tm} \}\ \cup \\&
\{(\mathrm{ns\_\!to\_\!list}(e) \append \langle v \rangle, \mathrm{ns\_\!to\_\!list}(e) \append \langle v \rangle) \mid (e, v) \in EnumValue_{Tm} \}\ \cup \\&
\{(\mathrm{ns\_\!to\_\!list}(e) \append \langle v \rangle, \mathrm{ns\_\!to\_\!list}(e)) \mid (e, v) \in EnumValue_{Tm} \} \\
abs =\ &\{\mathrm{ns\_\!to\_\!list}(t) \mid t \in Enum_{Tm}\}\ \\
\mathrm{mult}(e) =\ &\begin{cases}
    (0..\mstar, 1..1) &\mathrm{if}\ e \in \{(\mathrm{ns\_\!to\_\!list}(c), \langle f \rangle, \mathrm{ns\_\!to\_\!list}(e)) \mid (c, f) \in Field_{Tm} \land e \in Enum_{Tm}\}
\end{cases} \\
contains =\ &\{\}
\end{align*}
\isabellelref{tmod_enum_field_to_tg_enum_as_node_types_field_as_edge_type}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{defin}

\begin{thm}[Correctness of $f_{EnumFieldNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tmod_enum_field_to_tg_enum_as_node_types_field_as_edge_type_func}
$f_{EnumFieldNodes}(Tm)$ (\cref{defin:library_of_transformations:type_level_transformations:enum_fields:tmod_enum_field_to_tg_enum_as_node_types_field_as_edge_type}) is a valid transformation function in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_transformation_functions:transformation_function_type_model_type_graph} transforming $Tm_{EnumField}$ into $TG_{EnumFieldNodes}$.
\isabellelref{tmod_enum_field_to_tg_enum_as_node_types_field_as_edge_type_func}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{thm}

The proof of the correctness of $f_{EnumFieldNodes}$ will not be included here. Instead, it can be found in the validated Isabelle theories.

Finally, to complete the transformation, the transformation function that transforms $TG_{EnumFieldNodes}$ into $Tm_{EnumField}$ is defined:

\begin{defin}[Transformation function $f'_{EnumFieldNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_node_types_field_as_edge_type_to_tmod_enum_field}
The transformation function $f'_{EnumFieldNodes}(TG)$ is defined as:
\begin{align*}
Class =\ &\{\mathrm{list\_\!to\_\!ns}(n) \mid n \in NT_{TG} \land n = \mathrm{ns\_\!to\_\!list}(classtype) \} \\
Enum =\ &\{\mathrm{list\_\!to\_\!ns}(n) \mid n \in NT_{TG} \land n = \mathrm{ns\_\!to\_\!list}(enumid) \} \\
UserDataType =\ &\{\} \\
Field =\ &\{(\mathrm{list\_\!to\_\!ns}(\mathrm{src}(e)), l) \mid e \in ET_{TG} \land \langle l \rangle = \mathrm{lab}(e) \} \\
\mathrm{FieldSig} =\ &\begin{cases}
    (f, (fieldtype, 1..1)) &\mathrm{if}\ f \in \{(\mathrm{list\_\!to\_\!ns}(\mathrm{src}(e)), l) \mid e \in ET_{TG} \land \langle l \rangle = \mathrm{lab}(e) \}
\end{cases} \\
EnumValue =\ &\{(enumid, v) \mid v \in enumvalues\} \\
Inh =\ &\{\} \\
Prop =\ &\{\} \\
Constant =\ &\{\} \\
\mathrm{ConstType} =\ &\{\}
\end{align*}
\isabellelref{tg_enum_as_node_types_field_as_edge_type_to_tmod_enum_field}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{defin}

\begin{thm}[Correctness of $f'_{EnumFieldNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_node_types_field_as_edge_type_to_tmod_enum_field_func}
$f'_{EnumFieldNodes}(TG)$ (\cref{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_node_types_field_as_edge_type_to_tmod_enum_field}) is a valid transformation function in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_transformation_functions:transformation_function_type_graph_type_model} transforming $TG_{EnumFieldNodes}$ into $Tm_{EnumField}$.
\isabellelref{tg_enum_as_node_types_field_as_edge_type_to_tmod_enum_field_func}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{thm}

Once more, the correctness proof is not included here but can be found in the validated Isabelle proofs of this thesis.

\subsubsection{Encoding as edge type to an flag encoded enumeration type}

The second encoding for an enumeration type uses flags to encode the different values. The encoding corresponding to $Tm_{EnumField}$, in the case that the field references an enumeration type encoded as flags, can then be represented as $TG_{EnumFieldFlags}$, defined in the following definition:

\begin{defin}[Type graph $TG_{EnumFieldFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_flags_field_as_edge_type}
Let $TG_{EnumFieldFlags}$ be the type graph containing a node type which encodes the class type $classtype$.
Furthermore, $TG_{EnumFieldFlags}$ contains an encoded version of enumeration type $enumid$ with values from set $enumvalues$. This enumeration type is encoded using flags, as defined in $TG_{EnumFlags}$ (\cref{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_flags}). Finally, $TG_{EnumFieldFlags}$ defines an edge type from the encoded $classtype$ named $name$ to the encoded enumeration type $enumid$. $TG_{EnumFieldFlags}$ is defined as:
\begin{align*}
NT =\ &\{\mathrm{ns\_\!to\_\!list}(classtype), \mathrm{ns\_\!to\_\!list}(enumid)\}\\
ET =\ &\{(\mathrm{ns\_\!to\_\!list}(classtype), \langle name \rangle, \mathrm{ns\_\!to\_\!list}(enumid))\}\\
\!\!\sqsubseteq\ =\ &\{(\mathrm{ns\_\!to\_\!list}(classtype), \mathrm{ns\_\!to\_\!list}(classtype)),\ \\& (\mathrm{ns\_\!to\_\!list}(enumid), \mathrm{ns\_\!to\_\!list}(enumid))\}\\
abs =\ &\{\} \\
\mathrm{mult}(e) =\ &\begin{cases}
    (0..\mstar, 1..1) &\mathrm{if}\ e \in \{(\mathrm{ns\_\!to\_\!list}(classtype), \langle name \rangle, \mathrm{ns\_\!to\_\!list}(enumid))\}
\end{cases} \\
contains =\ &\{\}
\end{align*}
\isabellelref{tg_enum_as_flags_field_as_edge_type}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{defin}

\begin{thm}[Correctness of $TG_{EnumFieldFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_flags_field_as_edge_type_correct}
$TG_{EnumFieldFlags}$ (\cref{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_flags_field_as_edge_type}) is a valid type graph in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}.
\isabellelref{tg_enum_as_flags_field_as_edge_type_correct}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{thm}

A visual representation of $TG_{EnumFieldFlags}$ with edge name $\type{field}$ on node type $\type{Example}$ can be seen in \cref{fig:library_of_transformations:type_level_transformations:enum_fields:visualisation:groove_flags}. The field references the encoded enumeration type $\type{ExistingEnum}$ via the corresponding node type. The correctness proof of $TG_{EnumFieldFlags}$ is more involved, it is not included here for conciseness. It can be found within the validated Isabelle proofs.

In order to make composing transformation functions possible, $TG_{EnumFieldFlags}$ should be compatible with the type graph it is combined with.

\begin{thm}[Correctness of $\mathrm{combine}(TG, TG_{EnumFieldFlags})$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_flags_field_as_edge_type_combine_correct}
Assume a type graph $TG$ that is valid in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}. Then $TG$ is compatible with $TG_{EnumFieldFlags}$ (in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_graphs:compatibility}) if:
\begin{itemize}
    \item The node type of the encoded class type in $TG_{EnumFieldFlags}$ is already an node type in $TG$;
    \item All node types corresponding to the encoding of the enumeration type in $TG_{EnumFieldFlags}$ are already node types in $TG$;
    \item The node type of the encoded class type in $TG_{EnumFieldFlags}$ does not already have an edge type with the same name as the field in $TG$.
\end{itemize}
\isabellelref{tg_enum_as_flags_field_as_edge_type_combine_correct}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{thm}

\begin{proof}
Use \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_graphs:tg_combine_merge_correct}. It is possible to show that all assumptions hold. Now we have shown that $\mathrm{combine}(TG, TG_{EnumFieldFlags})$ is valid in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}.
\end{proof}

The next definitions define the transformation function from $Tm_{EnumField}$ to $TG_{EnumFieldFlags}$:

\begin{defin}[Transformation function $f_{EnumFieldFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tmod_enum_field_to_tg_enum_as_flags_field_as_edge_type}
The transformation function $f_{EnumFieldFlags}(Tm)$ is defined as:
\begin{align*}
NT =\ &\{\mathrm{ns\_\!to\_\!list}(t) \mid t \in Class_{Tm} \cup Enum_{Tm}\}\\
ET =\ &\{(\mathrm{ns\_\!to\_\!list}(c), \langle f \rangle, \mathrm{ns\_\!to\_\!list}(e)) \mid (c, f) \in Field_{Tm} \land e \in Enum_{Tm}\} \\
\!\!\sqsubseteq\ =\ &\{(\mathrm{ns\_\!to\_\!list}(x), \mathrm{ns\_\!to\_\!list}(x)) \mid x \in Class_{Tm} \cup Enum_{Tm} \}\\
abs =\ &\{\}\ \\
\mathrm{mult}(e) =\ &\begin{cases}
    (0..\mstar, 1..1) &\mathrm{if}\ e \in \{(\mathrm{ns\_\!to\_\!list}(c), \langle f \rangle, \mathrm{ns\_\!to\_\!list}(e)) \mid (c, f) \in Field_{Tm} \land e \in Enum_{Tm}\}
\end{cases} \\
contains =\ &\{\}
\end{align*}
\isabellelref{tmod_enum_field_to_tg_enum_as_flags_field_as_edge_type}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{defin}

\begin{thm}[Correctness of $f_{EnumFieldFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tmod_enum_field_to_tg_enum_as_flags_field_as_edge_type_func}
$f_{EnumFieldFlags}(Tm)$ (\cref{defin:library_of_transformations:type_level_transformations:enum_fields:tmod_enum_field_to_tg_enum_as_flags_field_as_edge_type}) is a valid transformation function in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_transformation_functions:transformation_function_type_model_type_graph} transforming $Tm_{EnumField}$ into $TG_{EnumFieldFlags}$.
\isabellelref{tmod_enum_field_to_tg_enum_as_flags_field_as_edge_type_func}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{thm}

The proof of the correctness of $f_{EnumFieldFlags}$ will not be included here. Instead, it can be found in the validated Isabelle theories.

Finally, to complete the transformation, the transformation function that transforms $TG_{EnumFieldFlags}$ into $Tm_{EnumField}$ is defined:

\begin{defin}[Transformation function $f'_{EnumFieldFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_flags_field_as_edge_type_to_tmod_enum_field}
The transformation function $f'_{EnumFieldFlags}(TG)$ is defined as:
\begin{align*}
Class =\ &\{\mathrm{list\_\!to\_\!ns}(n) \mid n \in NT_{TG} \land n = \mathrm{ns\_\!to\_\!list}(classtype) \} \\
Enum =\ &\{\mathrm{list\_\!to\_\!ns}(n) \mid n \in NT_{TG} \land n = \mathrm{ns\_\!to\_\!list}(enumid) \} \\
UserDataType =\ &\{\} \\
Field =\ &\{(\mathrm{list\_\!to\_\!ns}(\mathrm{src}(e)), l) \mid e \in ET_{TG} \land \langle l \rangle = \mathrm{lab}(e) \} \\
\mathrm{FieldSig} =\ &\begin{cases}
    (f, (fieldtype, 1..1)) &\mathrm{if}\ f \in \{(\mathrm{list\_\!to\_\!ns}(\mathrm{src}(e)), l) \mid e \in ET_{TG} \land \langle l \rangle = \mathrm{lab}(e) \}
\end{cases} \\
EnumValue =\ &\{(enumid, v) \mid v \in enumvalues\} \\
Inh =\ &\{\} \\
Prop =\ &\{\} \\
Constant =\ &\{\} \\
\mathrm{ConstType} =\ &\{\}
\end{align*}
\isabellelref{tg_enum_as_flags_field_as_edge_type_to_tmod_enum_field}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{defin}

\begin{thm}[Correctness of $f'_{EnumFieldFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_flags_field_as_edge_type_to_tmod_enum_field_func}
$f'_{EnumFieldFlags}(TG)$ (\cref{defin:library_of_transformations:type_level_transformations:enum_fields:tg_enum_as_flags_field_as_edge_type_to_tmod_enum_field}) is a valid transformation function in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_transformation_functions:transformation_function_type_graph_type_model} transforming $TG_{EnumFieldFlags}$ into $Tm_{EnumField}$.
\isabellelref{tg_enum_as_flags_field_as_edge_type_to_tmod_enum_field_func}{Ecore-GROOVE-Mapping-Library.EnumField}
\end{thm}

Once more, the correctness proof is not included here but can be found in the validated Isabelle proofs of this thesis.


GWT Model observations include the simulated groundwater concentration (\texttt{concentration}), and the mass flow, with units of mass per time, between two connected cells (\texttt{flow-ja-face}). The data required for each GWT Model observation type is defined in table~\ref{table:gwtobstype}. For \texttt{flow-ja-face} observation types, negative and positive values represent a loss from and gain to the \texttt{cellid} specified for ID, respectively.

\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}}
\caption{Available GWT model observation types} \tabularnewline

\hline
\hline
\textbf{Model} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\
\hline
\endhead

\hline
\endfoot

\input{../Common/gwt-obs.tex}
\label{table:gwtobstype}
\end{longtable}

\vspace{5mm}
\subsubsection{Example Observation Input File}

An example GWT Model observation file is shown below.

\lstinputlisting[style=inputfile]{./mf6ivar/examples/utl-obs-gwt-example.dat}