Пример #1
0
ExpressionNode *OperatorNode::SetOperand(unsigned num,
                                         const Expression &e) const {
  assert((_type == EXPR_FUNCTION || _type == EXPR_PREDICATE ||
          _type == EXPR_EQUALITY || _type == EXPR_DISEQUALITY ||
          _type == EXPR_AND || _type == EXPR_OR) && 0 <= num &&
         num < GetArity());

  std::vector<Expression> new_operands = _operands;
  new_operands[num] = e;
  return SetOperands(new_operands);
}
Пример #2
0
ExpressionNode *
OperatorNode::SelectOperands(const std::vector<unsigned> &indices) const {
  std::vector<Expression> new_operands;
  for (unsigned i = 0; i < GetArity(); i++) {
    for (unsigned j = 0; j < indices.size(); j++)
      if (j == i)
        new_operands.push_back(_operands[i]);
  }

  return SetOperands(new_operands);
}
Пример #3
0
ExpressionNode *OperatorNode::RemoveOperand(unsigned num) const {
  assert((_type == EXPR_FUNCTION || _type == EXPR_PREDICATE ||
          _type == EXPR_AND || _type == EXPR_OR) && 0 <= num &&
         num < GetArity());

  std::vector<Expression> new_operands = _operands;
  new_operands.erase(new_operands.begin() + num);

  assert(_operands.size() - 1 == new_operands.size());

  return SetOperands(new_operands);
}
Пример #4
0
    GenExpTLVec*
    CFGEnumeratorSingle::PopulateExpsOfGNCost(const GrammarNode* GN, uint32 Cost, bool Complete)
    {
        auto Retval = new GenExpTLVec();
        GNCostPair Key(GN, Cost);
        Done = false;
        auto Type = GN->GetType();
        PushExpansion(GN->ToString());
        auto const ExpansionTypeID = GetExpansionTypeID();

        auto FPVar = GN->As<GrammarFPVar>();
        // The base cases
        if (FPVar != nullptr) {
            return MakeBaseExpression<GenFPExpression>(Retval, FPVar->GetOp(), Type,
                                                       ExpansionTypeID, Cost, Key, Complete);
        }

        auto LetVar = GN->As<GrammarLetVar>();
        if (LetVar != nullptr) {
            return MakeBaseExpression<GenLetVarExpression>(Retval, LetVar->GetOp(), Type,
                                                           ExpansionTypeID, Cost, Key, Complete);
        }

        auto Const = GN->As<GrammarConst>();
        if (Const != nullptr) {
            return MakeBaseExpression<GenConstExpression>(Retval, Const->GetOp(), Type,
                                                          ExpansionTypeID, Cost, Key, Complete);
        }

        auto Func = GN->As<GrammarFunc>();

        if (Func != nullptr) {
            auto const& Args = Func->GetChildren();
            auto Op = Func->GetOp();
            const uint32 OpCost = Op->GetCost();
            const uint32 Arity = Op->GetArity();

            if (Cost < Arity + OpCost) {
                Retval->Freeze();
                ExpRepository[Key] = Retval;
                PopExpansion();
                return Retval;
            }
            PartitionGenerator* PG;
            if (Op->IsSymmetric() && Args[0] == Args[1]) {
                PG = new SymPartitionGenerator(Cost - OpCost);
            } else {
                PG = new PartitionGenerator(Cost - OpCost, Arity);
            }

            const uint32 NumPartitions = PG->Size();
            for (uint32 i = 0; i < NumPartitions; ++i) {

                auto Feasible = true;
                vector<const GenExpTLVec*> ArgExpVecs(Arity, nullptr);
                auto CurPartition = (*PG)[i];
                vector<GenExpTLVec::ConstIterator> Begins(Arity);
                vector<GenExpTLVec::ConstIterator> Ends(Arity);

                for (uint32 j = 0; j < Arity; ++j) {
                    auto CurVec = GetVecForGNCost(Args[j], CurPartition[j]);
                    if (CurVec == nullptr) {
                        CurVec = PopulateExpsOfGNCost(Args[j], CurPartition[j], false);
                    }
                    if (CurVec->Size() == 0) {
                        Feasible = false;
                        break;
                    } else {
                        ArgExpVecs[j] = CurVec;
                        Begins[j] = CurVec->Begin();
                        Ends[j] = CurVec->End();
                    }
                }

                if (!Feasible) {
                    continue;
                }

                // Iterate over the cross product
                auto CPGen = new CrossProductGenerator(Begins, Ends, GetPoolForSize(Arity));

                for (auto CurArgs = CPGen->GetNext();
                     CurArgs != nullptr;
                     CurArgs = CPGen->GetNext()) {

                    auto CurExp = new (FuncExpPool->malloc())
                        GenFuncExpression(static_cast<const InterpretedFuncOperator*>(Op), CurArgs);

                    auto Status =
                        (Complete ?
                         Solver->ExpressionCallBack(CurExp, Type, ExpansionTypeID, Index) :
                         Solver->SubExpressionCallBack(CurExp, Type, ExpansionTypeID));

                    if ((Status & DELETE_EXPRESSION) == 0) {
                        CPGen->RelinquishOwnerShip();
                        Retval->PushBack(CurExp);
                        NumExpsCached++;
                    } else {
                        FuncExpPool->free(CurExp);
                    }
                    if ((Status & STOP_ENUMERATION) != 0) {
                        Done = true;
                        break;
                    }
                }
                delete CPGen;
                if (Done) {
                    break;
                }
            }
            delete PG;

            Retval->Freeze();
            ExpRepository[Key] = Retval;
            PopExpansion();
            return Retval;
        }

        auto Let = GN->As<GrammarLet>();

        // We handle this in similar spirit as functions
        if (Let != nullptr) {
            auto const& Bindings = Let->GetBindings();
            const uint32 NumBindings = Bindings.size();
            const uint32 Arity = NumBindings + 1;
            auto BoundNode = Let->GetBoundExpression();
            const uint32 NumLetBoundVars = TheGrammar->GetNumLetBoundVars();

            if (Cost < Arity + 1) {
                Retval->Freeze();
                ExpRepository[Key] = Retval;
                PopExpansion();
                return Retval;
            }

            // Making a let binding incurs a cost of 1!
            auto PG = new PartitionGenerator(Cost - 1, Arity);
            const uint32 NumPartitions = PG->Size();
            for (uint32 i = 0; i < NumPartitions; ++i) {
                auto Feasible = true;
                vector<const GenExpTLVec*> ArgExpVecs(Arity, nullptr);
                auto CurPartition = (*PG)[i];
                vector<GenExpTLVec::ConstIterator> Begins(Arity);
                vector<GenExpTLVec::ConstIterator> Ends(Arity);

                uint32 j = 0;
                uint32* Positions = new uint32[NumBindings];

                for (auto it = Bindings.begin(); it != Bindings.end(); ++it) {
                    auto CurVec = GetVecForGNCost(it->second, CurPartition[j]);
                    if (CurVec == nullptr) {
                        CurVec = PopulateExpsOfGNCost(it->second, CurPartition[j], false);
                    }
                    if (CurVec->Size() == 0) {
                        Feasible = false;
                        break;
                    } else {
                        ArgExpVecs[j] = CurVec;
                        Begins[j] = CurVec->Begin();
                        Ends[j] = CurVec->End();
                    }
                    Positions[j] = it->first->GetOp()->GetPosition();
                    ++j;
                }

                if (!Feasible) {
                    delete[] Positions;
                    continue;
                }

                // Finally, the expression set for the bound expression
                auto BoundVec = GetVecForGNCost(BoundNode, CurPartition[j]);
                if (BoundVec == nullptr) {
                    BoundVec = PopulateExpsOfGNCost(BoundNode, CurPartition[j], false);
                }
                if (BoundVec->Size() == 0) {
                    // cross product is empty not feasible
                    delete[] Positions;
                    continue;
                } else {
                    ArgExpVecs[NumBindings] = BoundVec;
                    Begins[NumBindings] = BoundVec->Begin();
                    Ends[NumBindings] = BoundVec->End();
                }


                // Iterate over the cross product of expressions
                // The bindings object will be of size of the NUMBER
                // of let bound vars for the whole grammar
                auto CPGen = new CrossProductGenerator(Begins, Ends,
                                                       GetPoolForSize(Arity));
                GenExpressionBase const** BindVec = nullptr;
                auto BindVecPool = GetPoolForSize(NumLetBoundVars);

                for (auto CurArgs = CPGen->GetNext(); CurArgs != nullptr; CurArgs = CPGen->GetNext()) {
                    // We need to build the binding vector based on the position
                    if (BindVec == nullptr) {
                        BindVec = (GenExpressionBase const**)BindVecPool->malloc();
                        memset(BindVec, 0, sizeof(GenExpressionBase const*) * NumLetBoundVars);
                    }
                    for (uint32 k = 0; k < NumBindings; ++k) {
                        BindVec[Positions[k]] = CurArgs[k];
                    }

                    auto CurExp = new (LetExpPool->malloc())
                        GenLetExpression(BindVec, CurArgs[NumBindings], NumLetBoundVars);
                    auto Status =
                        (Complete ?
                         Solver->ExpressionCallBack(CurExp, Type, ExpansionTypeID, Index) :
                         Solver->SubExpressionCallBack(CurExp, Type, ExpansionTypeID));

                    if ((Status & DELETE_EXPRESSION) == 0) {
                        BindVec = nullptr;
                        Retval->PushBack(CurExp);
                        NumExpsCached++;
                    } else {
                        LetExpPool->free(CurExp);
                    }
                    if ((Status & STOP_ENUMERATION) != 0) {
                        Done = true;
                        break;
                    }
                }

                delete CPGen;
                delete[] Positions;

                if (Done) {
                    break;
                }
            }

            delete PG;

            Retval->Freeze();
            ExpRepository[Key] = Retval;
            PopExpansion();
            return Retval;
        }

        auto NT = GN->As<GrammarNonTerminal>();
        if (NT != nullptr) {
            const vector<GrammarNode*>& Expansions = TheGrammar->GetExpansions(NT);
            for (auto const& Expansion : Expansions) {
                auto CurVec = GetVecForGNCost(Expansion, Cost);
                if (CurVec == nullptr) {
                    CurVec = PopulateExpsOfGNCost(Expansion, Cost, Complete);
                }
                Retval->Merge(*CurVec);
                if (Done) {
                    break;
                }
            }
            Retval->Freeze();
            ExpRepository[Key] = Retval;
            PopExpansion();
            return Retval;
        }

        // Should NEVER get here
        throw InternalError((string)"You probably subclassed GrammarNode and forgot to change " +
                            "CFGEnumerator.cpp.\nAt: " + __FILE__ + ":" + to_string(__LINE__));
    }