// makes a deeop copy of the AST to avoid aliasing problems
AST* FunctionAST::copy_AST(AST* astVal)
{
    int     i;
    int     index[DIMENSIONS];    
    int     length;
    AST*    temp        = NULL;
    AST*    tempRoot    = NULL;
    AST*    AST0        = NULL;
    AST*    ASTi1       = NULL;
    AST*    AST_copy    = NULL; // = ast_create_item(0, NULL, NULL);

    if (!ast_is_instance(astVal, 2))
    {
        length  = ast_len(astVal);
        AST0    = ast_get_item(astVal, 0); 
        AST0->inheritedAddr = astVal->inheritedAddr;
 
        for (i=0; i<length-1; i++)
        {
            ASTi1   = ast_get_item(astVal, i + 1);
            if (ast_is_instance(ASTi1, 3)) ASTi1 = ASTi1->astVal;

            temp = this->copy_AST(ASTi1);
            AST0 = ast_insert_item(temp, AST0);
        }

        return AST0; 
    }
    else
    {
        tempRoot    = ast_create_item(0, astVal->nodeVal->copy(), NULL);
        return tempRoot;
    }
}
Exemple #2
0
static void
check_deps(const struct task *orig, const struct task *prev, ast_t expr)
{
	ast_t n;
	struct task *current;
	ast_itor_t itor;

	assert(orig);
	
	itor = new_ast_itor(expr);

	for (n = ast_itor_first(itor); n; n = ast_itor_next(itor)) {
		if (ast_get_type(n) != AST_ID)
			continue;

		current = ast_get_item(n);

		if (strcmp(orig->name, current->name) == 0)
			fatal_error("Circular dependency between `%s' and"
				    " `%s'.\n", prev ? prev->name : orig->name,
				    current->name);

		if (current->expr)
			check_deps(orig, current, current->expr);
	}

	delete_ast_itor(itor);
}
AST* FunctionAST::non_ready_operands(AST* evaluated_operands_list, AST* ready_operand_indices, int n, int l)
{
    int         i;
    int         j, i1, i2;
    int         le;
    int         lr;
    double*     coeff;
    double*     result_coeff;
    AST*        result_node;
    AST*        target_node;
    AST*        temp;
 
    le              = ast_len(evaluated_operands_list);
    lr              = ast_len(ready_operand_indices);
    result_coeff    = Vector_initialize(0, 0, this->k);


    int lenIndices = ast_len(ready_operand_indices);
    for (j=0; j<lenIndices; j++)
    {
        evaluated_operands_list = ast_delete_item(evaluated_operands_list, 
						  ast_get_item(ready_operand_indices, j)->intVal); 
    }

    // not implemented yet
    result_node = ast_create_item(0, this->create_node(NULL, result_coeff, n, l, 1), NULL);

    // if all the operands are available for computing
    // then the operation is complete. Just replace the 
    // operation node wiht the result node
    if (le == lr)
    {
        if (n == this->max_level) result_node->nodeVal->is_ready = 1;
        printf ("(1)\n");
        return result_node;
    }
    // the operation is not complete yet. Some operands
    // are still at internal nodes
    else
    {
        AST*    op = ast_create_item(NON_OPERATOR, NULL, NULL);

        printf ("===============\n");
        ast_print_tree(op, 0, 0);
        printf ("\n");
        ast_print_tree(evaluated_operands_list, 0, 0);
        printf ("\n");
        ast_print_tree(result_node, 0, 0);
        printf ("\n");

        evaluated_operands_list = ast_put_item(op, evaluated_operands_list);
        evaluated_operands_list = ast_insert_item(result_node, evaluated_operands_list);

        ast_print_tree(evaluated_operands_list, 0, 0);
        printf ("\n");
        printf ("(2)\n");
        return evaluated_operands_list;
    }
}
Exemple #4
0
bool ast_check_calculated_AST(AST* target, AST* subtree)
{
/*
    printf (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
    printf ("[%s]\n", __func__);
    printf (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
*/
    int     i;
    int     lenTarget;
    int     lenSubtree;
    AST*    tempTarget;
    AST*    tempSubtree;

    lenTarget   = ast_len(target);
    lenSubtree  = ast_len(subtree);

    // Basic Unit!
    if (lenTarget == 1 && lenSubtree == 1)
    {
        // (1) Node
        if (target->nodeVal != NULL && subtree->nodeVal != NULL)
        {
            if (target->nodeVal->function != subtree->nodeVal->function)
                return false;
        }
        // (2) Operation
        else
        {
            if (target->intVal != subtree->intVal)
                return false;
        }
        return true;
    }
    // Several Units
    else
    {
        // (1) Both ASTs should have the same number of ASTs
        if (lenTarget == lenSubtree)
        {
            for (i=0; i<lenTarget; i++)
            {
                count_check++;
                tempTarget  = ast_get_item(target, i);
                count_check++;
                tempSubtree = ast_get_item(subtree, i);

                if (tempTarget->astVal != NULL)
                {
                    if (tempSubtree->astVal != NULL)
                    {
                        if (ast_check_calculated_AST(tempTarget->astVal, tempSubtree->astVal) == true)
                        {
                            count_free++;
                            free(tempTarget);
                            count_free++;
                            free(tempSubtree);
                            continue;
                        }
                        else
                        {
                            count_free++;
                            free(tempTarget);
                            count_free++;
                            free(tempSubtree);
                            return false; 
                        }
                    }
                    else
                    {
                            count_free++;
                            free(tempTarget);
                            count_free++;
                            free(tempSubtree);
                        return false;
                    }
                }
                else
                {
                    if (tempSubtree->astVal != NULL)
                    {
                            count_free++;
                            free(tempTarget);
                            count_free++;
                            free(tempSubtree);
                        return false;
                    }
                    else
                    {
                        if (ast_check_calculated_AST(tempTarget, tempSubtree) == true)
                        {
                            count_free++;
                            free(tempTarget);
                            count_free++;
                            free(tempSubtree);
                            continue;
                        }
                        else
                        {
                            count_free++;
                            free(tempTarget);
                            count_free++;
                            free(tempSubtree);
                            return false;
                        }
                    }
                }
            }
            return true;
        }
        else
        {
            return false;
        }
    }
}
// Inner 
AST* FunctionAST::inner_ready_operands(AST* evaluated_operands_list, AST* ready_operand_indices, int n, int l, double* inheritedResult)
{
    //printf ("[%s][%4d, %4d]\n", __func__, n, l);
    int		i, j;
    int 	i1, i2;
    int		le, lr;
    double*	coeff;
    double*	result_coeff;

    AST*	    result_node;
    AST*	    target_node;
    AST*	    temp;	
    FunctionAST*    tempFunc    = NULL;

    le			= ast_len(evaluated_operands_list);
    lr			= ast_len(ready_operand_indices);
    temp		= ast_search_item(ready_operand_indices, 0);
    target_node		= ast_search_item(evaluated_operands_list, temp->intVal);
    result_coeff	= this->get_coeff_from_parent(target_node, n, l);



    // iterating over operands whose coefficients are available
    for (j=0; j<ast_len(ready_operand_indices) - 1; j++)
    {
#ifdef DEBUG
        printf ("[%s][%4d, %4d]: ", __func__, n, l);
#endif
        temp		= ast_search_item(ready_operand_indices, j + 1);
        target_node	= ast_search_item(evaluated_operands_list, temp->intVal);
        coeff		= this->get_coeff_from_parent(target_node, n, l);
        result_coeff	= this->inner_coefficients(result_coeff, coeff, inheritedResult);
        tempFunc        = target_node->nodeVal->function;
        
#ifdef DEBUG
        printf (">> %12.8f:%12.8f(%p)\n", result_coeff[0], *inheritedResult, inheritedResult);
#endif
    }
    
#ifdef DEBUG
    printf ("after calculating result_coeff\n");
#endif
    // sorts in reverse order so that operands can be popped off
    // of teh evaluated_operands_list without messing up the
    // indices
    int 	tempIndex;
    int		tempIndex1;
    AST*	tempIdx;
    AST* 	tempIdx1;

    for (i1=0; i1<lr; i1++)
    {
        for (i2=0; i2<lr-1; i2++)
        {
            tempIndex 	= ast_search_item(ready_operand_indices, i2)->intVal;
            tempIndex1	= ast_search_item(ready_operand_indices, i2 + 1)->intVal;

            if (tempIndex < tempIndex1)
            {
                tempIdx 	    = ast_search_item(ready_operand_indices, i2);
                tempIdx->intVal     = tempIndex1;

                tempIdx1 	    = ast_search_item(ready_operand_indices, i2 + 1);
                tempIdx1->intVal    = tempIndex;
            }
        }
    }

    // deletes ?
    for (j = 0; j<ast_len(ready_operand_indices); j++)
    {
        evaluated_operands_list = ast_delete_item(evaluated_operands_list,
						  ast_get_item(ready_operand_indices, j)->intVal);
    }

    // not implemented yet
    result_node = ast_create_item(0, this->create_node(NULL, result_coeff, n, l, 1), NULL);
    //result_node->nodeVal->inheritedInner = result_coeff[0];

    // if all the operands are available for computing
    // then the operation is complete. Just replace the 
    // operation node with the result node.
    if (le == lr)
    {
        if (n == this->max_level) result_node->nodeVal->is_ready = 1;
        return result_node;
    }
    // the operation is not complete yet. Some operands
    // are still at internal nodes.
    else
    {
        AST* op = ast_create_item(INNER_OPERATOR, NULL, NULL);
        evaluated_operands_list = ast_put_item(op, evaluated_operands_list);
        evaluated_operands_list = ast_insert_item(result_node, evaluated_operands_list);

	return evaluated_operands_list;
    }
}
AST* FunctionAST::evaluate_AST(AST* astVal, AST* rawVal, int n, int l, AST* newRoot, AST* rawRoot)
{
#ifdef DEBUG_EVAL
    printf ("=================================================================================================\n");
    printf ("[%s][%4d, %4d]\n", __func__, n, l);
//#ifdef DEBUG_EVAL
    printf ("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    ast_print_tree(astVal, 0, 0);
    printf ("\n------------------------------------------------------\n");
    //ast_print_tree(rawVal, 0, 0);
    //printf ("\n------------------------------------------------------\n");
    ast_print_tree(newRoot, 0, 0);
    printf ("\n------------------------------------------------------\n");
    //ast_print_tree(rawRoot, 0, 0);
    //printf ("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
#endif
    int     i; 
    int     num_operand;
    double* inheritedResult             = NULL;
    AST*    op                          = NULL;
    AST*    realOp                      = NULL;
    AST*    opRaw                       = NULL;
    AST*    operand                     = NULL;
    AST*    operandRaw                  = NULL; 
    AST*    evaluated_operand           = NULL;
    AST*    evaluated_operands_list     = NULL;
    AST*    ready_operands_indices      = NULL; // composed of integer
    AST*    coeff                       = NULL;
    AST*    reuseAST                    = NULL;
    AST*    existAST                    = NULL;

    // binary associative operator
    if (ast_len(astVal) > 2)
    {   
        op                  = ast_get_item(astVal, 0);
        realOp              = ast_search_item(astVal, 0);
        opRaw               = ast_get_item(rawVal, 0);
        op->inheritedAddr   = astVal->inheritedAddr;
        inheritedResult     = op->inheritedAddr;
        num_operand         = ast_len(astVal) - 1;

	// How to handle operands
        for (i=1; i<num_operand+1; i++)
        {  
            operand         = ast_get_item(astVal, i);
            operandRaw      = ast_get_item(rawVal, i);

            // if the operand is an expression then evaluate that expression
            if (!ast_is_instance(operand, 2))
            {  
                if (ast_is_instance(operand, 3))
		    // operand == AST
                { 
                    if (ast_is_instance(operandRaw, 3))
                        evaluated_operand = this->evaluate_AST(operand->astVal, operandRaw->astVal, 
							       n, l, newRoot, rawRoot);
                    else
                        evaluated_operand = this->evaluate_AST(operand->astVal, operandRaw, 
							       n, l, newRoot, rawRoot); 
                }
                else
		    // operand == Integer
                {
                    evaluated_operand   = this->evaluate_AST(operand, operandRaw,  n, l, newRoot, rawRoot);
                }
            }
            // check if the node has coefficients ready at this level
            else
            {
                evaluated_operand   = this->pre_compute(op, operand, n, l);
            }

#ifdef DEBUG
            printf ("<<<<<<<<<<<<<<<<<< evaluated_operand(%d) <<<<<<<<<<<<<<<<<<<<<<\n", i);
            ast_print_tree(evaluated_operand, 0, 0);
            printf ("\n");
            printf ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
#endif


            // add the evaluated operand to compputed list
            evaluated_operands_list = ast_insert_item(evaluated_operand, 
						      evaluated_operands_list); 

            // if the operand is a single function then check if
            // it has coefficients and add to the coeff list if
            // it does
            if (ast_is_instance(evaluated_operand, 2))
            {
                if (evaluated_operand->nodeVal->is_ready) 
                {
                    AST* temp = ast_create_item(i - 1, NULL, NULL);
                    ready_operands_indices = ast_insert_item(temp, ready_operands_indices);
                }
            } 
        }
#ifdef DEBUG
        printf ("<<<<<<<<<<<<<<<<<< evaluated_operands_list <<<<<<<<<<<<<<<<<<<<<<\n");
        ast_print_tree(evaluated_operands_list, 0, 0);
        printf ("\n");
        printf ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
#endif
        //
        //
        //  Please check whether evaluated_operands_list is correct or not
        //
        //
        // compute the sum for set of operands whose coefficients are available
        if (ast_len(ready_operands_indices) > 1)
        {
#ifdef DEBUG_EVAL
	    printf ("[%s][%4d, %4d] evaluated by binary_op()\n", __func__, n, l);
#endif
            AST* hot;
        
            realOp->calculated = true;
            hot =  this->binary_operation(op, evaluated_operands_list, ready_operands_indices, n, l, inheritedResult);
            return hot;
            //return this->binary_operation(op, evaluated_operands_list, ready_operands_indices, n, l, inheritedResult);
        }
        else
        {
            evaluated_operands_list = ast_put_item(op, evaluated_operands_list);
        }
#ifdef DEBUG_EVAL
	printf ("[%s][%4d, %4d] evaluated by ast_put_item()\n", __func__, n, l);
#endif
        return evaluated_operands_list;             
    }

    //
    //
    // unary operation
    //
    //
    if (ast_len(astVal) == 2)
    {
        op          = ast_get_item(astVal, 0);
        realOp      = ast_search_item(astVal, 0);
        opRaw       = ast_get_item(rawVal, 0);
        operand     = ast_get_item(astVal, 1);
        operandRaw  = ast_get_item(rawVal, 1);
     

        // To Check This Binary Operation...
        reuseAST            = this->check_evaluated_AST(astVal, rawVal, newRoot, rawRoot);

/*
//#ifdef DEBUG_EVAL
if (reuseAST != NULL) 
{
if (reuseAST->right != NULL)
{
if (reuseAST->right->nodeVal != NULL)
{
if (reuseAST->right->nodeVal->calculatedCoeff != NULL)
{
existAST = ast_create_item(0, this->create_node(NULL, reuseAST->right->nodeVal->calculatedCoeff, n, l, 1), NULL);   
printf ("\t>>>>>> EXIST <<<<<<\n");
//ast_print_tree(existAST, 0, 0);
//printf ("\n");
return existAST;
}
}
}
}               
*/
/*
  printf ("~~[exist!] (%d, %d)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", n, l);
  ast_print_tree(reuseAST, 2, 0);
  printf ("\n");
  ast_print_tree(reuseAST, 3, 0);
  printf ("\n");
  printf ("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");

  existAST = ast_create_item(0, this->create_node(NULL, reuseAST->right->nodeVal->calculatedCoeff, n, l, 1), NULL);
 
  printf (">>>>>>>>>> !!!!!! <<<<<<<<<<<<<<\n");
  ast_print_tree(existAST, 2, 0);
  printf ("\n");
  printf (">>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<\n");

  return existAST;
  }
*/
//#endif
        // if the operand is an experssion then evaluate that expression 
        if (!ast_is_instance(operand, 2))
        {  
            if (ast_is_instance(operand, 3)) printf ("this is ast!!! why do not push ast??\n");
            
            evaluated_operand   = this->evaluate_AST(operand, operandRaw, n, l, newRoot, rawRoot);
        }
        // if the operand is a single function then just
        // evaluate it to see if it has coefficients, update
        // the node by assigning coefficient if it has any
        else
        {
            evaluated_operand   = this->pre_compute(op, operand, n, l);
        }
#ifdef DEBUG      
        printf ("<<<<<<<<<<<<<<<<<< evaluated_operand <<<<<<<<<<<<<<<<<<<<<<\n");
        ast_print_tree(evaluated_operand, 0, 0);
        printf ("\n");
        printf ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
#endif
        // 
        //
        //
        if (ast_is_instance(evaluated_operand, 2) && evaluated_operand->nodeVal->is_ready)
        {   
#ifdef DEBUG_EVAL
	    printf ("[%s][%4d, %4d] evaluated by unary_op()\n", __func__, n, l);
#endif
            realOp->calculated = true;
            AST*    cold;
            AST*    cool;
            cool    = evaluated_operand;    
#ifdef DEBUG
            printf ("---------------------------------------------------\n");
            printf ("before unary-operation: evaluated_operand\n");
            ast_print_tree(evaluated_operand, 2, 0);
            printf ("---------------------------------------------------\n");
#endif
            cold = this->unary_operation(op, evaluated_operand, n, l, reuseAST); 
#ifdef DEBUG
            printf ("<<<<<<<<<< cold <<<<<<<<<<<<<\n");
            ast_print_tree(cold, 2, 1);
            printf ("\n");
            printf ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
#endif
            // assignment result to the old AST
            if (evaluated_operand->nodeVal != NULL && cold->nodeVal != NULL)
                evaluated_operand->nodeVal->calculatedCoeff = cold->nodeVal->coeff; 
#ifdef DEBUG            
            printf ("---------------------------------------------------\n");
            printf ("after unary-operation: evaluated_operand\n");
            ast_print_tree(evaluated_operand, 2, 0);
            printf ("\n");
            ast_print_tree(evaluated_operand, 3, 0);
            printf ("---------------------------------------------------\n");
#endif

            return cold;
            //return this->unary_operation(op, evaluated_operand, n, l); 
        }
        else
        {
            evaluated_operands_list = ast_insert_item(op, evaluated_operands_list);
            evaluated_operands_list = ast_insert_item(evaluated_operand, 
						      evaluated_operands_list);
#ifdef DEBUG_EVAL
	    printf ("[%s][%4d, %4d] evaluated by ast_insert_item()\n", __func__, n, l);
#endif
            return evaluated_operands_list;
        }
    }
}
//  
// Assumption: target <= subTree
//  
// This function is to check whether "target" AST is already calculated in "subTree".
// Then, it returns the calculated AST in "subTree"
//
AST* FunctionAST::check_evaluated_AST(AST* target, AST* targetRaw, AST* subtree, AST* subtreeRaw)
{
#ifdef DEBUG_REUSE
    printf ("[%s]\n", __func__);
    printf ("[target] --------------------------------------------------------------------------------------\n");
    ast_print_tree(target, 0, 0);
    printf ("\n---------------------------------------------------------------------------------------------\n");
    printf ("[subtree] -------------------------------------------------------------------------------------\n");
    ast_print_tree(subtree, 0, 0);
    printf ("\n>>>------------------------------------------------------------------------------------------\n");
#endif
    int     i;
    int     numTargetOperands;
    int     numTargetRawOperands;
    int     numSubtreeOperands;
    int     numSubtreeRawOperands;    

    AST*    targetOp;
    AST*    targetRawOp;
    AST*    targetOperand;
    AST*    targetRawOperand;
    AST*    subtreeOp;
    AST*    subtreeRawOp;
    AST*    subtreeOperand;
    AST*    subtreeRawOperand;

    AST*    resultAST;

    // related to Target        
    targetOp                = ast_search_item(target, 0);
    targetRawOp             = ast_search_item(targetRaw, 0);
    numTargetOperands       = ast_len(target) - 1;
    numTargetRawOperands    = ast_len(targetRaw) - 1;


    // related to Subtree
    subtreeOp               = ast_search_item(subtree, 0);
    subtreeRawOp            = ast_search_item(subtreeRaw, 0);
    numSubtreeOperands      = ast_len(subtree) - 1;
    numSubtreeRawOperands   = ast_len(subtreeRaw) - 1;

#ifdef DEBUG_REUSE_1
    //  Basically, target is identical to targetRaw
    //  However, it can be different because of modified AST.
    printf ("targetOp: %d(%d), the # of operands: %d(%d)\n", targetOp->intVal, targetRawOp->intVal, numTargetOperands, numTargetRawOperands);
    printf ("subtreeOp: %d(%d), the # of operands: %d(%d)\n", subtreeOp->intVal, subtreeRawOp->intVal, numSubtreeOperands, numSubtreeRawOperands);
#endif

    //  
    //  target vs. subtree
    //    
    if (subtreeOp->intVal == targetOp->intVal)
    {
        if (subtreeOp->calculated == true)
        {
            //  This subtree's operation-type is identical with target's one.
            //  Furthermore, it is also already calculated.
            //  It checks whether "subtree" is identical to "target" literally.
            if (ast_check_calculated_AST(target, subtree) == true)
            {
                //printf (">>>>> found <<<<<\n");
                return subtree;
            }
        }
    }

    //  target vs. subtree's child
    i = 1;
    while ((i < numSubtreeOperands + 1) && (i < numSubtreeRawOperands + 1))
    {
#ifdef DEBUG_REUSE
        printf ("(%d/%d) : (%d/%d)\n", i, numSubtreeOperands, i, numSubtreeRawOperands);
#endif
        //subtreeOperand      = ast_search_item(subtree, i);
        //subtreeRawOperand   = ast_search_item(subtreeRaw, i);            
        subtreeOperand      = ast_get_item(subtree, i);
        subtreeRawOperand   = ast_get_item(subtreeRaw, i);            

        if (subtreeOperand->astVal != NULL)
        {
            if (subtreeRawOperand->astVal != NULL)
            {
                resultAST   = this->check_evaluated_AST(target, targetRaw, subtreeOperand->astVal, subtreeRawOperand->astVal);
                if (resultAST != NULL)
                    return resultAST;
            }
            else
            {
                resultAST   = this->check_evaluated_AST(target, targetRaw, subtreeOperand->astVal, subtreeRawOperand);
                if (resultAST != NULL)
                    return resultAST;
            }
        }
        else
        {
            if (subtreeRawOperand->astVal != NULL)
            {
                resultAST   = this->check_evaluated_AST(target, targetRaw, subtreeOperand, subtreeRawOperand->astVal);
                if (resultAST != NULL)
                    return resultAST;
            }
            else
            {
                resultAST   = this->check_evaluated_AST(target, targetRaw, subtreeOperand, subtreeRawOperand);
                if (resultAST != NULL)
                    return resultAST;
            }
        }

        i++;
    }
    return NULL; 
}
AST* FunctionAST::multiply_ready_operands(AST* evaluated_operands_list, AST* ready_operand_indices, int n, int l)
{
    // not implemented yet 
    int         j, i1, i2; 
    int         lr;
    int         temp1, temp2;
    double*     coeff1              = NULL;
    double*     coeff2              = NULL;
    double*     result_coeff        = NULL;
    AST*        temp                = NULL;
    AST*        target              = NULL;
    AST*        result_node         = NULL;
    AST*        result_node_list    = NULL;
    AST*        tempItem            = NULL;
    AST*        tempItem1           = NULL;

    // iterating over operands whose coefficients are available
    lr  = ast_len(ready_operand_indices);

    for (j=0; j<lr-1; j+=j+2)
    {
        temp    = ast_search_item(ready_operand_indices, j);
        target  = ast_search_item(evaluated_operands_list, temp->intVal);
        coeff1  = this->get_coeff_from_parent(target, n, l);
        
        temp    = ast_search_item(ready_operand_indices, j + 1);
        target  = ast_search_item(evaluated_operands_list, temp->intVal);
        coeff2  = this->get_coeff_from_parent(target, n, l);

        result_coeff    = this->multiply_coefficients(coeff1, coeff2, n);
       
        // not implemented yet
        result_node = ast_create_item(0, this->create_node(NULL, result_coeff, n, l, 0), NULL);
        result_node_list = ast_insert_item(result_node, result_node_list);
    }

    if (lr % 2)
    {   
        tempItem    = ast_search_item(ready_operand_indices, lr - 1);
        tempItem1   = ast_search_item(evaluated_operands_list, tempItem->intVal); 
        result_node_list = ast_insert_item(tempItem1, result_node_list);
    }
    
    // sorts in reverse order so that operands can be popped off
    // of the evaluated_operands_list without messing up the
    // indices
    for (i1; i1<lr; i1++)
    {
        for (i2; i2<lr-1; i2++)
        {
            temp1   = ast_search_item(ready_operand_indices, i2)->intVal;
            temp2   = ast_search_item(ready_operand_indices, i2 + 1)->intVal;

            if (temp1 < temp2)
            {
                ast_search_item(ready_operand_indices, i2)->intVal      = temp2;
                ast_search_item(ready_operand_indices, i2 + 1)->intVal  = temp1;
            }
        }
    }

    for (j=0; j<ast_len(ready_operand_indices); j++)
    {
        evaluated_operands_list = ast_delete_item(evaluated_operands_list, 
						  ast_get_item(ready_operand_indices, j)->intVal);
    }

    evaluated_operands_list = ast_extend_item(evaluated_operands_list, result_node_list);

    // if all the operands are available for computing
    // then the operation is complete. Just replace the 
    // operation node with the result node
    AST* returnOp = NULL;
    if (ast_len(evaluated_operands_list) == 1)
    {
        returnOp = ast_get_item(evaluated_operands_list, 0);
        if (n == this->func->max_level)
        {
            returnOp->nodeVal->is_ready = 1;
        }    

        returnOp->right = NULL;
        return returnOp;
    }
    else
    {
        returnOp = ast_create_item(MULTIPLY_OPERATOR, NULL, NULL);
        evaluated_operands_list = ast_put_item(returnOp, evaluated_operands_list);
        return evaluated_operands_list;
    }
}
AST* FunctionAST::add_ready_operands(AST* evaluated_operands_list, AST* ready_operand_indices, int n, int l)
{
    int         i;
    int         j, i1, i2;
    int         le;
    int         lr;
    double*     coeff;
    double*     result_coeff;
    AST*        result_node;
    AST*        target_node;
    AST*        temp;
 
    le              = ast_len(evaluated_operands_list);
    lr              = ast_len(ready_operand_indices);
    temp            = ast_search_item(ready_operand_indices, 0);
    target_node     = ast_search_item(evaluated_operands_list, temp->intVal);
    result_coeff    = this->get_coeff_from_parent(target_node, n, l);

/*
 *  Temporally Disabled (Example AST does not have ADD).
 *
 // iterating over operands whose coefficients are available
 for (j=0; j<ast_len(ready_operand_indices) - 1; j++)
 {
 temp            = ast_search_item(ready_operand_indices, j + 1);
 target_node     = ast_search_item(evaluated_operands_list, temp->intVal);
 coeff           = this->get_coeff_from_parent(target_node, n, l);
 result_coeff    = this->add_coefficients(result_coeff, coeff);
 }
*/

    // sorts in reverse order so that operands can be popped off
    // of the evaluated_operands_list without messing up the
    // indices
    int     tempIndex;
    int     tempIndex1;
    AST*    tempIdx;
    AST*    tempIdx1;
    
    for (i1=0; i1<lr; i1++)
    {
        for (i2=0; i2<lr-1; i2++)
        {
            tempIndex   = ast_search_item(ready_operand_indices, i2)->intVal;
            tempIndex1  = ast_search_item(ready_operand_indices, i2 + 1)->intVal;
    
            if (tempIndex < tempIndex1)
            {
                tempIdx = ast_search_item(ready_operand_indices, i2);
                tempIdx->intVal = tempIndex1;

                tempIdx1 = ast_search_item(ready_operand_indices, i2 + 1);
                tempIdx1->intVal = tempIndex;
            }
        }
    }

    int lenIndices = ast_len(ready_operand_indices);
    for (j=0; j<lenIndices; j++)
    {
        evaluated_operands_list = ast_delete_item(evaluated_operands_list, 
						  ast_get_item(ready_operand_indices, j)->intVal); 
    }

    // not implemented yet
    result_node = ast_create_item(0, this->create_node(NULL, result_coeff, n, l, 1), NULL);

    // if all the operands are available for computing
    // then the operation is complete. Just replace the 
    // operation node wiht the result node
    if (le == lr)
    {
        if (n == this->max_level) result_node->nodeVal->is_ready = 1;
        return result_node;
    }
    // the operation is not complete yet. Some operands
    // are still at internal nodes
    else
    {
        AST*    op = ast_create_item(ADD_OPERATOR, NULL, NULL);
        evaluated_operands_list = ast_put_item(op, evaluated_operands_list);
        evaluated_operands_list = ast_insert_item(result_node, evaluated_operands_list);

        return evaluated_operands_list;
    }
}