function DelPair($relation, $srcConcept, $srcAtom, $tgtConcept, $tgtAtom)
{
    if ($srcAtom === "") {
        ExecEngineSHOUTS("DelPair: srcAtom is empty string.");
    }
    if ($srcAtom === "") {
        ExecEngineSHOUTS("DelPair: tgtAtom is empty string.");
    }
    /* 
    $relationTableInfo from Generics.php 
    contains array with all relations, for each relation the following is specified: 
     - srcConcept : srcConcept of relation
     - tgtConcept : tgtConcept of relation
     - table : database table in which the relation is populated
     - srcCol : column of database table in which the srcConcept is placed
     - tgtCol : column of database table in which the tgtConcept is placed
    */
    global $relationTableInfo;
    /* 
    $tableColumInfo from Generics.php 
    contains array with all database tables and their columns, for each tablecolumn the following is specified: 
     - concept : the atoms of which concept are set here
     - unique : whether or not the value in the column must be unique. 'true' for properties
     - null   : whether or not the value in the column can be NULL. in case of UNI relations
    */
    global $tableColumnInfo;
    // check if $relation appears in $relationTableInfo
    $found = false;
    foreach ($relationTableInfo as $key => $arr) {
        if ($key == "rel_" . $relation . "_" . $srcConcept . "_" . $tgtConcept) {
            $found = true;
            $table = $arr['table'];
            $srcCol = $arr['srcCol'];
            $tgtCol = $arr['tgtCol'];
        }
    }
    if (!$found) {
        // Errors in ADL script may corrupt the database, so we die (leaving a suicide note)
        ExecEngineSHOUTS("ERROR: Cannot find {$relation}\\[{$srcConcept}\\*{$tgtConcept}\\] signature.");
        ExecEngineSays("DelPair({$relation},{$srcConcept},{$srcAtom},{$tgtConcept},{$tgtAtom})");
        ExecEngineSays("If you have defined this relation in Ampersand, then you must be sure to also have defined an INTERFACE that uses this relation (or else it does not show up in the PHP relation administration.");
        die;
    }
    // get table column properties for $srcCol and $tgtCol
    $srcColUnique = $tableColumnInfo[$table][$srcCol]['unique'];
    $srcColNull = $tableColumnInfo[$table][$srcCol]['null'];
    $tgtColUnique = $tableColumnInfo[$table][$tgtCol]['unique'];
    $tgtColNull = $tableColumnInfo[$table][$tgtCol]['null'];
    // SQL escape table, column and atom names
    $tableEsc = escapeSQL($table);
    $srcColEsc = escapeSQL($srcCol);
    $tgtColEsc = escapeSQL($tgtCol);
    $srcAtomEsc = escapeSQL($srcAtom);
    $tgtAtomEsc = escapeSQL($tgtAtom);
    // generate database query
    if ($srcColNull xor $tgtColNull) {
        if ($srcColNull) {
            $query = "UPDATE `{$tableEsc}` SET `{$srcColEsc}`=NULL WHERE `{$srcColEsc}`='{$srcAtomEsc}' AND `{$tgtColEsc}`='{$tgtAtomEsc}'";
        } else {
            $query = "UPDATE `{$tableEsc}` SET `{$tgtColEsc}`=NULL WHERE `{$srcColEsc}`='{$srcAtomEsc}' AND `{$tgtColEsc}`='{$tgtAtomEsc}'";
        }
    } elseif ($srcColNull and $tgtColNull) {
        $query = "DELETE FROM `{$tableEsc}` WHERE `{$srcColEsc}`='{$srcAtomEsc}' AND `{$tgtColEsc}`='{$tgtAtomEsc}';";
    } else {
        // neither srcCol nor tgtCol can be null ==> delete query
        $query = "DELETE FROM `{$tableEsc}` WHERE `{$srcColEsc}`='{$srcAtomEsc}' AND `{$tgtColEsc}`='{$tgtAtomEsc}';";
    }
    // execute database query
    queryDb($query);
    // log
    ExecEngineWhispers("Delete pair ({$srcAtom},{$tgtAtom}) from {$relation}({$srcConcept}*{$tgtConcept})");
    emitLog("DelPair({$relation},{$srcConcept},{$srcAtom},{$tgtConcept},{$tgtAtom})");
    emitLog($query);
}
function checkRules($ruleNames)
{
    global $allRoles;
    global $allRulesSql;
    global $selectedRoleNr;
    global $execEningeIsVerySilent;
    // set in 'pluginsettings.php'
    global $ExecEngineRules;
    // array met alle ruleNames van de ExecEngine
    if (!isset($ExecEngineRules)) {
        foreach ($allRoles as $role) {
            if ($role['name'] == 'ExecEngine') {
                $ExecEngineRules = $role['ruleNames'];
                break;
            }
        }
    }
    global $MappingEngineRules;
    // array met alle ruleNames van de MappingEngine
    if (!isset($MappingEngineRules)) {
        foreach ($allRoles as $role) {
            if ($role['name'] == 'MappingEngine') {
                $MappingEngineRules = $role['ruleNames'];
                break;
            }
        }
    }
    $allRulesHold = true;
    // by default $allRulesHold = true
    $error = '';
    foreach ($ruleNames as $ruleName) {
        if (is_array($MappingEngineRules) and in_array($ruleName, $MappingEngineRules)) {
            continue;
        }
        // Mapping rules are skipped here for performance reasons
        $ruleSql = $allRulesSql[$ruleName];
        $rows = DB_doquerErr($ruleSql['violationsSQL'], $error);
        // execute violationsSQL to check for violations
        if ($error) {
            error("While evaluating rule '{$ruleName}': " . $error);
        }
        // if there are rows (i.e. violations)
        if (count($rows) == 0) {
            // emitLog('Rule '.$ruleSql['name'].' holds');
        } else {
            $allRulesHold = false;
            emitLog('Rule ' . $ruleSql['name'] . ' is broken');
            // if the rule has an associated message, we show that instead of the name and the meaning
            $message = $ruleSql['message'] ? $ruleSql['message'] : "Rule '{$ruleSql['name']}' is broken: {$ruleSql['meaning']}";
            // however, for ExecEngine output we have the possibility to suppress some stuff
            if (isset($ExecEngineRules)) {
                if (in_array($ruleName, $ExecEngineRules)) {
                    ExecEngineSays("[{EE} restored '{$ruleName}']");
                    ExecEngineWhispers($message);
                } else {
                    emitAmpersandLog($message);
                }
            } else {
                emitAmpersandLog($message);
            }
            $srcNrOfIfcs = getNrOfInterfaces($ruleSql['srcConcept'], $selectedRoleNr);
            $tgtNrOfIfcs = getNrOfInterfaces($ruleSql['tgtConcept'], $selectedRoleNr);
            $pairView = $ruleSql['pairView'];
            // pairView contains an array with the fragments of the violations message (if specified)
            global $violationID;
            $violationID = 0;
            // For optimization purposes, e.g. for computing transitive closures (see plugin_Warshall.php)
            foreach ($rows as $violation) {
                $violationID++;
                if ($pairView[0]['segmentType'] == 'Text' && strpos($pairView[0]['Text'], '{EX}') === 0) {
                    $theMessage = execPair($violation['src'], $ruleSql['srcConcept'], $violation['tgt'], $ruleSql['tgtConcept'], $pairView);
                    // emitAmpersandLog($theMessage);
                    $theCleanMessage = strip_tags($theMessage);
                    $theCleanMessage = substr($theCleanMessage, 4);
                    // Strip {EX} tag
                    $functionsToBeCalled = explode('{EX}', $theCleanMessage);
                    // Split off subsequent function calls
                    if (count($functionsToBeCalled) > 1) {
                        ExecEngineWhispers("[[START]]");
                    }
                    foreach ($functionsToBeCalled as $functionToBeCalled) {
                        $params = explode(';', $functionToBeCalled);
                        // Split off variables
                        $cleanparams = array();
                        foreach ($params as $param) {
                            $cleanparams[] = trim($param);
                        }
                        $params = $cleanparams;
                        unset($cleanparams);
                        ExecEngineWhispers($functionToBeCalled);
                        $func = array_shift($params);
                        // First parameter is function name
                        if (function_exists($func)) {
                            call_user_func_array($func, $params);
                        } else {
                            ExecEngineSHOUTS("TODO: Create function {$func} with " . count($params) . " parameters.");
                        }
                    }
                    if (count($functionsToBeCalled) > 1) {
                        ExecEngineWhispers("[[DONE]]");
                    }
                } else {
                    $theMessage = showPair($violation['src'], $ruleSql['srcConcept'], $srcNrOfIfcs, $violation['tgt'], $ruleSql['tgtConcept'], $tgtNrOfIfcs, $pairView);
                    emitAmpersandLog('- ' . $theMessage);
                }
            }
        }
    }
    return $allRulesHold;
}