// creates a predicate object from an AST parse tree
boost::shared_ptr< Predicate > createPredicate( const TreeIter& it )
{
	std::string op( it->value.begin(), it->value.end() );
	
	if ( it->value.id() == PredicateGrammar::predicateId )
	{
		if ( op == "&&" )
			return boost::shared_ptr< Predicate >( new PredicateAnd( 
				createPredicate( it->children.begin() ), createPredicate( it->children.begin() + 1 ) ) );
		else if ( op == "||" )
			return boost::shared_ptr< Predicate >( new PredicateOr( 
				createPredicate( it->children.begin() ), createPredicate( it->children.begin() + 1 ) ) );
		else
			UBITRACK_THROW( "Bad predicate: " + op );
	}
	else if ( it->value.id() == PredicateGrammar::statementId )
	{
		if ( op == "!" )
			return boost::shared_ptr< Predicate >( new PredicateNot( createPredicate( it->children.begin() ) ) );
		else
			UBITRACK_THROW( "Bad statement: " + op );
	}
	else if ( it->value.id() == PredicateGrammar::compOpId )
	{
		if ( it->children.size() == 2 )
			return boost::shared_ptr< Predicate >( new PredicateCompare( op, 
				createValue( it->children.begin() ), createValue( it->children.begin() + 1 ) ) );

		// hack: spirit prunes empty string constants out of the tree
		if ( it->children.size() == 1 )
			return boost::shared_ptr< Predicate >( new PredicateCompare( op, 
				createValue( it->children.begin() ), 
				boost::shared_ptr< AttributeExpression >( new AttributeExpressionConstant( "" ) ) ) );
		
		UBITRACK_THROW( "Problem with comparison parsing: illegal numer of children" );
	}
	else if ( it->value.id() == PredicateGrammar::predicateFunctionId )
	{
		// parse parameters into vector
		std::vector< boost::shared_ptr< AttributeExpression > > params;
		for ( TreeIter itParam = it->children.begin(); itParam != it->children.end(); itParam++ )
			params.push_back( createValue( itParam ) );

		return boost::shared_ptr< Predicate >( new PredicateFunction( op, params ) );
	}
	else
	{
		UBITRACK_THROW( "bad predicate" );
	}
}
Example #2
0
/*
 * Caller is responsible for deleting returned Predicate* if necessary
 */
Predicate* Domain::getNonEvidenceAtom(const int& index) const
{
  int predId = -1;
  int numAtomsPerPred;
  int numAtoms = 0;
  for (int i = 0; i < getNumPredicates(); i++)
  {
    numAtomsPerPred = (*numNonEvidAtomsPerPred_)[i];
    if (numAtoms + numAtomsPerPred >= index + 1)
    {
      predId = i;
      break;
    }
    numAtoms += numAtomsPerPred;
  }
  assert(predId >= 0);

    // Get the newIndex-th grounding of f.o. pred with id predId   
  Predicate* pred = createPredicate(predId, false);
    // Not all groundings of pred are non-evidence, so we need the while loop
  bool foundNE = false;
  while(!foundNE)
  {
    for (int i = 0; i < pred->getNumTerms(); i++)
    {
      int termType = pred->getTermTypeAsInt(i);
      const Array<int>* constantsByType = getConstantsByType(termType);
      int constIdx = random() % constantsByType->size();
      pred->setTermToConstant(i, (*constantsByType)[constIdx]);
    }
    assert(pred->isGrounded());
    if (!db_->getEvidenceStatus(pred)) foundNE = true;
  }
  return pred;
}
Example #3
0
  //Caller is responsible for deleting Array and its contents
void Domain::createPredicates(Array<Predicate*>* const & preds,
                              const bool& includeEqualPreds) const
{
  for (int i = 0; i < getNumPredicates(); i++)
  {
    Predicate* p = createPredicate(i, includeEqualPreds);
    if (p) preds->append(p);
  }
}
Example #4
0
  //Caller is responsible for deleting Array and its contents
void Domain::createPredicates(Array<Predicate*>* const & preds,
                              const Array<string>* const & predNames)
{
  for (int i = 0; i < predNames->size(); i++)
  {
    int predId = getPredicateId((*predNames)[i].c_str());    
    Predicate* p = createPredicate(predId, true);
    if (p) preds->append(p);
  }
}
Example #5
0
std::shared_ptr<Operand> PredicateParser::createOperand(const std::string& fullExpression, int idxOpFrom, int idxOpTo, size_t from, size_t to)
{
    auto pPredicate = createPredicate(fullExpression, idxOpFrom, idxOpTo, from, to);
    auto pOperand = std::dynamic_pointer_cast<Operand>(pPredicate);
    if(nullptr != pOperand)
    {
        return pOperand;
    }
    else
    {
        return std::make_shared<PredicateOperand>(pPredicate);
    }
}
Example #6
0
std::shared_ptr<Predicate> PredicateParser::createPredicate(const std::string& fullExpression, int idxOpFrom, int idxOpTo, size_t from, size_t to)
{
    if(idxOpFrom  >= idxOpTo)
    {
        unpackBrackets(fullExpression, from, to);
        PredicateParser childParaser(false);
        childParaser.parse(fullExpression, from, to);
        return childParaser.getResult();
    }
    else
    {
        auto idxLowerest = idxOpFrom;
        for(auto idxCur = idxLowerest + 1; idxCur < idxOpTo; ++idxCur)
        {
            if(mOperators[idxLowerest] > mOperators[idxCur])
            {
                idxLowerest = idxCur;
            }
        }

        auto& opInfo = mOperators[idxLowerest];
        if(mOperators[idxLowerest].isUnary())
        {
            auto pChild = createPredicate(fullExpression, idxLowerest + 1, idxOpTo, opInfo.to, to);
            auto pUnary = createUnary(opInfo, pChild);
            return pUnary;
        }
        else
        {
            auto leftFrom = from;
            auto rightTo = to;

            auto pArthemetic = createArthemeticOp(opInfo);
            if(nullptr != pArthemetic)
            {
                auto pLeft = createOperand(fullExpression, idxOpFrom, idxLowerest, leftFrom, opInfo.from);
                auto pRight = createOperand(fullExpression, idxLowerest + 1, idxOpTo, opInfo.to, rightTo);

                pArthemetic->setLeft(pLeft);
                pArthemetic->setRight(pRight);

                return pArthemetic;
            }

            auto pCompare = createCompOp(opInfo);
            if(nullptr != pCompare)
            {
                auto pLeft = createOperand(fullExpression, idxOpFrom, idxLowerest, leftFrom, opInfo.from);
                auto pRight = createOperand(fullExpression, idxLowerest + 1, idxOpTo, opInfo.to, rightTo);

                pCompare->setLeft(pLeft);
                pCompare->setRight(pRight);

                return pCompare;
            }

            auto pLogic = createLogicOp(opInfo);
            if(nullptr != pLogic)
            {
                auto pLeft = createPredicate(fullExpression, idxOpFrom, idxLowerest, leftFrom, opInfo.from);
                auto pRight = createPredicate(fullExpression, idxLowerest + 1, idxOpTo, opInfo.to, rightTo);

                pLogic->setLeft(pLeft);
                pLogic->setRight(pRight);

                return pLogic;
            }

            throw std::logic_error("unknow operator");
        }
    }
}
Example #7
0
void PredicateParser::parse(const std::string& fullExpression, size_t& fromPos, size_t endPos)
{
    assert(0 != fromPos);
    std::stack<char> unmatched;
    if(mRootParser)
    {
        unmatched.push('{');
        ++fromPos;
    }

    fromPos = skipSpace(fullExpression, fromPos, endPos);
    auto oldFrom = fromPos;
    size_t outerSize = unmatched.size();

    for(; fromPos < endPos && !(mRootParser && unmatched.empty()); ++fromPos)
    {
        char c = fullExpression.at(fromPos);
        if(!matchRange(unmatched, fullExpression, fromPos, endPos) && outerSize == unmatched.size())
        {

            switch(c)
            {
            case '=':
                parseEqual(fullExpression, fromPos);
                break;
            case '!':
                parseNonEqual(fullExpression, fromPos);
                break;
            case '>':
                parseGreat(fullExpression, fromPos);
                break;
            case '<':
                parseLess(fullExpression, fromPos);
                break;
            case '^':
                parseStartsWith(fullExpression, fromPos);
                break;
            case '$':
                parseEndsWith(fullExpression, fromPos);
                break;
            case '*':
                parseContains(fullExpression, fromPos);
                break;
            case '~':
                parseMatch(fullExpression, fromPos);
                break;
            case '&':
                parseAnd(fullExpression, fromPos);
                break;
            case '|':
                parseOr(fullExpression, fromPos);
                break;
            case '+':
                mOperators.emplace_back(OpInfo{OpInfo::Add, fromPos, fromPos + 1, mOperators.size()});
                break;
            case '-':
                {
                    size_t lastOpEnd = mOperators.empty() ? oldFrom : mOperators.back().to;
                    int from = fromPos - 1;
                    bool isMinus = isSpace(fullExpression, from , lastOpEnd - 1, -1);

                    if(isMinus)
                    {
                        mOperators.emplace_back(OpInfo{OpInfo::Minus, fromPos, fromPos + 1, mOperators.size()});
                    }
                    else
                    {
                        mOperators.emplace_back(OpInfo{OpInfo::Sub, fromPos, fromPos + 1, mOperators.size()});
                    }
                    break;
                }
            case '/':
                {
                    auto lastOp = mOperators.empty() ? nullptr : &mOperators.back();
                    size_t lastOpEnd = nullptr == lastOp ? oldFrom : lastOp->to;
                    int from = fromPos - 1;
                    bool allSpace = isSpace(fullExpression, from , lastOpEnd - 1, -1);
                    if(nullptr != lastOp && (lastOp->op >= OpInfo::Match) && (lastOp->op <= OpInfo::iNotMatch) && lastOp->to == (from - 1))
                    {
                        
                    }

                    if((oldFrom != fromPos) && (mOperators.empty() || (mOperators.back().op < OpInfo::Match) && (mOperators.back().op > OpInfo::iNotMatch)))
                    {
                        mOperators.emplace_back(OpInfo{OpInfo::Div, fromPos, fromPos + 1, mOperators.size()});
                    }
                    else
                    {
                        fromPos = skip2(fullExpression, fromPos + 1, '/', endPos) + 1;
                    }
                }
                break;
            case '%':
                mOperators.emplace_back(OpInfo{OpInfo::Mod, fromPos, fromPos + 1, mOperators.size()});
                break;
            default:
                break;
            }
        }//match range
    }//foreach char

    auto newEnd = fromPos - (mRootParser ? 1 : 0);
    if(mOperators.empty() && '(' != fullExpression.at(oldFrom))
    {
        auto pOperand = createPrimitive(fullExpression, oldFrom, newEnd);
        mResult = pOperand;
    }
    else
    {
        auto pPredicate = createPredicate(fullExpression, 0, mOperators.size(), oldFrom, newEnd);
        mResult = pPredicate;
    }
}