Example #1
0
	/**
	 * Attaches expressions and constraints to the plans. Called by the AlicaEngine during start up.
	 */
	void ExpressionHandler::attachAll()
	{
		PlanRepository* pr = ae->getPlanRepository();
		for (auto it : pr->getPlans())
		{
			auto p = it.second;

			auto ufGen = utilityCreator->createUtility(p->getId());
			p->setUtilityFunction(ufGen->getUtilityFunction(p));

			if (p->getPreCondition() != nullptr)
			{
				if (p->getPreCondition()->isEnabled())
				{
					p->getPreCondition()->setBasicCondition(
							this->conditionCreator->createConditions(p->getPreCondition()->getId()));
					attachConstraint(p->getPreCondition());
				}
				else
				{
					p->getPreCondition()->setBasicCondition(make_shared<BasicFalseCondition>());
				}
			}

			if (p->getRuntimeCondition() != nullptr)
			{
				p->getRuntimeCondition()->setBasicCondition(
						this->conditionCreator->createConditions(p->getRuntimeCondition()->getId()));
				attachConstraint(p->getRuntimeCondition());
			}

			for (auto t : p->getTransitions())
			{
				if (t->getPreCondition() != nullptr)
				{
					if (t->getPreCondition()->isEnabled())
					{
						t->getPreCondition()->setBasicCondition(
								this->conditionCreator->createConditions(t->getPreCondition()->getId()));
						attachConstraint(t->getPreCondition());
					}
					else
					{
						t->getPreCondition()->setBasicCondition(make_shared<BasicFalseCondition>());
					}
				}
			}
		}
	}
Example #2
0
//merges dfas to one dfa for traversal
lexer_word_repr* lexer_dfa_builder::mergeDfas(const std::vector<lexer_word_repr*>* const words, DfaManager& dfaManager) const
{
    lexer_word_repr* start = dfaManager.createLexerWordRepr();

    //So each JOB consists of:
    //  1) a ptr to dfa node where we left off in mergeToWord
    //  2) a transition that we suspect is placeable in mergetToWord
    //  3) a vector of dfa nodes already visited in mergeTo, this prevents folding the fromDfa back "itself"
    //      but in reality there should be at path dinstinguishing mergeFrom from mergeTo that doesn't visit
    //      a node in MergeTo twice. This only makes sense, because the "going back itself" thing is strictly for
    //      kleen closure like behaviour on runtime. The minimal "description" of automata is actually constant 
    //      and doesn't need to have two nodes twice.
    //      repeated.
    auto jobQueue = new std::vector<std::vector<std::tuple<lexer_dfa*, LexerTransition, std::vector<lexer_dfa*>>>*>();

    for (int i = 0; i < words->size(); i++)
    {
        auto jobVector = new std::vector<std::tuple<lexer_dfa*, LexerTransition, std::vector<lexer_dfa*>>>();
        jobQueue->push_back(jobVector);
    }

    std::cout << std::endl << "Merging dfas to one, words size: " << words->size() << std::endl;

    //iterate through words
    int jobLineIndex = 0;
    for (int i =0; i < words->size(); i++)
    {
        lexer_dfa* word = words->at(i);
        std::cout << word << std::endl;
        std::cout << word->getId() << std::endl;

        lexer_dfa* mergeToDfaPtr = start;
        lexer_dfa* mergeFromDfaPtr = word;

        std::vector<LexerTransition> nextTransitions = mergeFromDfaPtr->getTransitions();

        DeLOG("Getting transitions for word\n")

        for (auto transition : nextTransitions)
        {
            DeLOG("Adding job to job Queue\n");

            std::tuple<lexer_dfa*, LexerTransition, std::vector<lexer_dfa*>> job(mergeToDfaPtr, transition, std::vector<lexer_dfa*>{});
            (jobQueue->at(jobLineIndex))->push_back(job);
        }

        jobLineIndex++;
    }

    DeLOG(std::string("\nMerge Process: ").append(std::to_string(jobQueue->size())).append(" job lines(queues) total\n").c_str());

    for (jobLineIndex = 0; jobLineIndex < jobQueue->size(); jobLineIndex++)
    {
        DeLOG(std::string("Processing Job line #").append(std::to_string(jobLineIndex+1)).append("\n").c_str());
        auto jobVector = jobQueue->at(jobLineIndex);
        while (jobVector->size() != 0)
        {
            DeLOG(std::string("\nThere are ").append(std::to_string(jobVector->size())).append(" in job vector. Processing Job #").append(std::to_string(jobLineIndex + 1)).append("\n").c_str());

            auto currJobTuple = jobVector->back();
            jobVector->pop_back();

            auto currMergeToDfaPtr = std::get<0>(currJobTuple);

            //here we'll check the currMergeToDfaPtr against the previously visited ptrs in MergeTo
            //if we've already visited it, we know to ignore it this transition (and NOT to put job back in queue)
            auto ptrsInMergeToAlreadyVisited = std::get<2>(currJobTuple);
            auto skipAndContinue = false;
            for (auto mergeToDfaPtrVisited : ptrsInMergeToAlreadyVisited)
            {
                if (currMergeToDfaPtr == mergeToDfaPtrVisited)
                {
                    skipAndContinue = true;
                    break;
                }
            }

            if (skipAndContinue)
            {
                continue;
            }

            ptrsInMergeToAlreadyVisited.push_back(currMergeToDfaPtr);

            auto transitionFromCurrMergeFromDfaPtr = std::get<1>(currJobTuple);            
            auto nextMergeFromDfaPtr = transitionFromCurrMergeFromDfaPtr.getDfaNode();
            const auto si = transitionFromCurrMergeFromDfaPtr.getStateAndInput();

            DeLOG(std::string{"si = {"}.append(std::to_string(si.getState())).append(1, si.getInput()).append("}\n").c_str());

            auto nextMergeToDfaPtrCandidateInfo1 = currMergeToDfaPtr->getNextDfaForInput(si.getInput(), false); 
            auto nextMergeToDfaPtrCandidateProperties1 = nextMergeToDfaPtrCandidateInfo1.second;

            auto nextMergeToDfaPtrCandidateInfo2 = currMergeToDfaPtr->getNextDfaForInput(si.getInput(), true);
            auto nextMergeToDfaPtrCandidateProperties2 = nextMergeToDfaPtrCandidateInfo2.second;
            
            //aka mergeFromDfaProperties
            const auto currentMergeFromTransitionProperties = transitionFromCurrMergeFromDfaPtr.getProperties();

            if (checkForProperty(currentMergeFromTransitionProperties, Lexer_Dfa_Properties::ISA_PUSH_DOWN_CONTINUANCE)
                 || checkForProperty(currentMergeFromTransitionProperties, Lexer_Dfa_Properties::ISA_PUSH_DOWN_EJECT))
            {
              //If the transition ~to~ current ~mergeFrom~ dfa has the
              // properties: PUSH_DOWN_EJECT or PUSH_DOWN_CONTINUANCE,
              // then we assume we are in a state of recursion. If the
              // recursive pathway in ~mergeTo~ dfa is not taken,
              // nextMergeaToDfaPtrCandidatePropertes is 0x0, then we
              // add the current ~mergeFrom~ dfa (noting that it is for a
              // recursion (stack-count > 0) to the currMergeToDfa. 
              // If the position is filled, properties != 0x0 in dfaInfo
              // when we query with param indicating stackCount > 0,
              // then we push the ~nextMergeTo~ dfa into thejobQueue
              // (along with the properties of this is not already being
              // done (like w\ the entire transition))

              lexer_dfa* nextMergeToDfaPtr = nullptr;
              if (nextMergeToDfaPtrCandidateProperties2 != 0x0)
              { 
                nextMergeToDfaPtr = nextMergeToDfaPtrCandidateInfo2.first;
              }

              currMergeToDfaPtr->_printTransitions();
              std::cout << "is there nextDfaPtr? " << (nextMergeToDfaPtr != nullptr ? "yes" : "no")
                      << nextMergeToDfaPtr << std::endl;

              if (nextMergeToDfaPtr == nullptr)
              {
                LexerStateAndInput aLexerStateAndInput = transitionFromCurrMergeFromDfaPtr.getStateAndInput();

                DeLOG(std::string{"::adding transition(["}.append(std::to_string(aLexerStateAndInput.getState())).append(", '").append(1, aLexerStateAndInput.getInput()).append("']->").append(1, nextMergeFromDfaPtr->getId()).append(") to dfa(").append(1, currMergeToDfaPtr->getId()).append(")\n").c_str());

                StateAndInput<int,char> aStateAndInput(aLexerStateAndInput.getState(), aLexerStateAndInput.getInput(), transitionFromCurrMergeFromDfaPtr.getIsRanged());
                currMergeToDfaPtr->add_next_dfa(aStateAndInput, nextMergeFromDfaPtr, currentMergeFromTransitionProperties);

                //Sanity check
                auto nextMergeToDfaPtrCandidateInfoSanity = currMergeToDfaPtr->getNextDfaForInput(si.getInput(), true);
                auto nextMergeToDfaPtrCandidatePropertiesSanity = nextMergeToDfaPtrCandidateInfoSanity.second;

                if (nextMergeToDfaPtrCandidateInfoSanity.first == nullptr)
                {
                  perror("\nCould not find Node. Exiting.\n");
                  exit(EXIT_FAILURE);
                }

              }
              else
              {
                std::vector<LexerTransition> nextTransitions = nextMergeFromDfaPtr->getTransitions();

                for (auto transitionFromNextMergeFromDfa : nextTransitions)
                {
                  const auto si = transitionFromNextMergeFromDfa.getStateAndInput();
                  DeLOG(std::string{"Couldn't find an opening, pushing back job { to add ("}.append(std::to_string(si.getState())).append(",").append(1, si.getInput()).append(") from dfa-id(").append(std::to_string(nextMergeToDfaPtr->getId())).append(")\n").c_str());

                  std::tuple<lexer_dfa*, LexerTransition, std::vector<lexer_dfa*>> job(const_cast<lexer_dfa*>(nextMergeToDfaPtr), transitionFromNextMergeFromDfa, ptrsInMergeToAlreadyVisited);

                  jobVector->push_back(job);
                }                
              }
            }
            else if (checkForProperty(currentMergeFromTransitionProperties, Lexer_Dfa_Properties::ISA_NORMAL) 
              || checkForProperty(currentMergeFromTransitionProperties, Lexer_Dfa_Properties::ISA_PUSH_DOWN_ACTIVATOR))
            {
              //Likewise if the transition ~to~ current ~mergeFrom~ dfa 
              // has the properties: NORMAL or PUSH_DOWN_ACTIVATOR,
              // then we assume then we assume a non-recursive (even if
              // by the top top level lexer perspective this has yet to
              // be determined. If the non-recursive pathway in ~mergeTo~
              // dfa is not taken, then we add the current ~mergeTo~ dfa
              // (noting that it is for a recursion (stack-count > 0).
              // If the position is filled (non-nullptr) dfa result for
              // query with stackCount > 0 param, then we push the
              // ~nextMergeTo~ into thejobQueue.            
              lexer_dfa* nextMergeToDfaPtr = nullptr;

              if (nextMergeToDfaPtrCandidateProperties1 != 0x0)
              {
                 nextMergeToDfaPtr = nextMergeToDfaPtrCandidateInfo1.first;
              }

              currMergeToDfaPtr->_printTransitions();
              std::cout << "is there nextDfaPtr? " << (nextMergeToDfaPtr != nullptr ? "yes" : "no")
                        << nextMergeToDfaPtr << std::endl;

              if (nextMergeToDfaPtr == nullptr)
              {
                LexerStateAndInput aLexerStateAndInput = transitionFromCurrMergeFromDfaPtr.getStateAndInput();

                DeLOG(std::string{"::adding transition(["}.append(std::to_string(aLexerStateAndInput.getState())).append(", '").append(1, aLexerStateAndInput.getInput()).append("']->").append(1, nextMergeFromDfaPtr->getId()).append(") to dfa(").append(1, currMergeToDfaPtr->getId()).append(")\n").c_str());

                StateAndInput<int,char> aStateAndInput(aLexerStateAndInput.getState(), aLexerStateAndInput.getInput(), transitionFromCurrMergeFromDfaPtr.getIsRanged());
                currMergeToDfaPtr->add_next_dfa(aStateAndInput, nextMergeFromDfaPtr, currentMergeFromTransitionProperties);                

                //Sanity check
                auto nextMergeToDfaPtrCandidateInfoSanity = currMergeToDfaPtr->getNextDfaForInput(si.getInput(), false);
                auto nextMergeToDfaPtrCandidatePropertiesSanity = nextMergeToDfaPtrCandidateInfoSanity;

                if (nextMergeToDfaPtrCandidateInfoSanity.first == nullptr)
                {
                  perror("\nYeah, this is bad. After we just added our new transition to merged rep, we can't query for it. The effect of adding a new transition should be immediate (I don't know why it should ever not be...). Exiting.\n");
                  exit(EXIT_FAILURE);
                }
              }
              else
              {
                std::vector<LexerTransition> nextTransitions = nextMergeFromDfaPtr->getTransitions();

                for (auto transitionFromNextMergeFromDfa : nextTransitions)
                {
                  const auto si = transitionFromNextMergeFromDfa.getStateAndInput();
                  DeLOG(std::string{"Couldn't find an opening, pushing back job { to add ("}.append(std::to_string(si.getState())).append(",").append(1, si.getInput()).append(") from dfa-id(").append(std::to_string(nextMergeToDfaPtr->getId())).append(")\n").c_str());

                  std::tuple<lexer_dfa*, LexerTransition, std::vector<lexer_dfa*>> job(const_cast<lexer_dfa*>(nextMergeToDfaPtr), transitionFromNextMergeFromDfa, ptrsInMergeToAlreadyVisited);

                  jobVector->push_back(job);
                }
              }
            }
            else
            {
              std::cout << "Undefined language specification: duplicate lexer words?" << std::endl;
              exit(1);
            }

        }

        delete jobVector;
    }

    delete jobQueue;

    std::cout << "Finished jobs!" << std::endl << std::endl;

    return start;
}