/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Author: pgess <v.melnychenko@xreate.org>
 * Created on June 7, 2018, 6:01 PM
 *
 * \file    latereasoning.cpp
 * \brief   Late reasoninf support
 */

#include "aux/latereasoning.h"
#include "analysis/interpretation.h"
#include "ast.h"

using namespace std;

namespace xreate{
namespace latereasoning{

LateAnnotation::LateAnnotation(const Gringo::Symbol& symbolStatic) {
    guardedContent.push_back(pair<list<Gringo::Symbol>, Gringo::Symbol>({}, symbolStatic));
}

boost::optional<Gringo::Symbol>
LateAnnotation::select(const std::list<Expression>& keys, AST* root, TranscendLayer* transcend) const {
    for(const auto& entry : guardedContent) {
        const std::list<Gringo::Symbol>& guardsExpected = entry.first;
        auto keyPSIt = guardKeys.begin();
        auto keyActualIt = keys.begin();
        bool result = true;
        for(const Gringo::Symbol& guardExpectedGS : guardsExpected) {
            auto keyS = transcend->unpack(*keyPSIt);
            const ExpandedType& keyT = root->getType(CodeScope::getDefinition(keyS));
            const ExpandedType& keyTPlain = keyT->__operator == TypeOperator::SLAVE ?
                interpretation::dereferenceSlaveType(keyT, transcend)
                : keyT;
            Expression guardExpectedE = interpretation::representTransExpression(
                guardExpectedGS, keyTPlain, transcend);
            if(!(guardExpectedE == *keyActualIt)) {
                result = false;
                break;
            }
            ++keyActualIt;
            ++keyPSIt;
        }
        if(!result) continue;
        return entry.second;
    }

    return boost::none;
}

}
}

