Пример #1
0
/**
 * Visits the given ASTNode as a function.  For this node only the
 * traversal is preorder.
 */
void
FormulaFormatter_visitFunction ( const ASTNode_t *parent,
                                 const ASTNode_t *node,
                                 StringBuffer_t  *sb )
{
  unsigned int numChildren = ASTNode_getNumChildren(node);
  unsigned int n;


  FormulaFormatter_format(sb, node);
  StringBuffer_appendChar(sb, '(');

  if (numChildren > 0)
  {
    FormulaFormatter_visit( node, ASTNode_getChild(node, 0), sb );
  }

  for (n = 1; n < numChildren; n++)
  {
    StringBuffer_appendChar(sb, ',');
    StringBuffer_appendChar(sb, ' ');
    FormulaFormatter_visit( node, ASTNode_getChild(node, n), sb );
  }

  StringBuffer_appendChar(sb, ')');
}
Пример #2
0
/**
 * Visits the given ASTNode node.  This function is really just a
 * dispatcher to either SBML_formulaToL3String_visitFunction() or
 * SBML_formulaToL3String_visitOther().
 */
void
L3FormulaFormatter_visit ( const ASTNode_t *parent,
                           const ASTNode_t *node,
                           StringBuffer_t  *sb, 
                           const L3ParserSettings_t *settings )
{

  if (ASTNode_isLog10(node))
  {
    L3FormulaFormatter_visitLog10(parent, node, sb, settings);
  }
  else if (ASTNode_isSqrt(node))
  {
    L3FormulaFormatter_visitSqrt(parent, node, sb, settings);
  }
  else if (isTranslatedModulo(node))
  {
    L3FormulaFormatter_visitModulo(parent, node, sb, settings);
  }
  else if (L3FormulaFormatter_isFunction(node, settings))
  {
    L3FormulaFormatter_visitFunction(parent, node, sb, settings);
  }
  else if (ASTNode_isUMinus(node))
  {
    L3FormulaFormatter_visitUMinus(parent, node, sb, settings);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_LOGICAL_NOT, 1))
  {
    L3FormulaFormatter_visitUNot(parent, node, sb, settings);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_QUALIFIER_LOGBASE, 1))
  {
    L3FormulaFormatter_visit(node, ASTNode_getChild(node, 0), sb, settings);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_QUALIFIER_DEGREE, 1))
  {
    L3FormulaFormatter_visit(node, ASTNode_getChild(node, 0), sb, settings);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_SEMANTICS, 1))
  {
    L3FormulaFormatter_visit(node, ASTNode_getChild(node, 0), sb, settings);
  }
  else
  {
    L3FormulaFormatter_visitOther(parent, node, sb, settings);
  }
}
Пример #3
0
void
printFunctionDefinition (unsigned int n, FunctionDefinition_t *fd)
{
  const ASTNode_t *math;
  char *formula;


  if ( FunctionDefinition_isSetMath(fd) )
  {
    math = FunctionDefinition_getMath(fd);

    /* Print function body. */
    if (ASTNode_getNumChildren(math) == 0)
    {
      printf("(no body defined)");
    }
    else
    {
      math    = ASTNode_getChild(math, ASTNode_getNumChildren(math) - 1);
      formula = SBML_formulaToDot(math);
      fprintf(fout, "subgraph cluster%u {\n", noClusters);
      fprintf(fout, "label=\"FunctionDefinition: %s\";\n%s\n", FunctionDefinition_getId(fd), formula);
      free(formula);
      noClusters++;
    }
  }
}
Пример #4
0
/**
 * Visits the given ASTNode and continues the inorder traversal.
 */
void
L3FormulaFormatter_visitOther ( const ASTNode_t *parent,
                                const ASTNode_t *node,
                                StringBuffer_t  *sb, 
                                const L3ParserSettings_t *settings )
{
  unsigned int numChildren = ASTNode_getNumChildren(node);
  unsigned int group       = L3FormulaFormatter_isGrouped(parent, node, settings);
  unsigned int n;


  if (group)
  {
    StringBuffer_appendChar(sb, '(');
  }

  if (numChildren == 0) {
    L3FormulaFormatter_format(sb, node, settings);
  }

  else if (numChildren == 1)
  {
    //I believe this would only be called for invalid ASTNode setups,
    // but this could in theory occur.  This is the safest 
    // behavior I can think of.
    L3FormulaFormatter_format(sb, node, settings);
    StringBuffer_appendChar(sb, '(');
    L3FormulaFormatter_visit( node, ASTNode_getChild(node, 0), sb, settings);
    StringBuffer_appendChar(sb, ')');
  }

  else {
    L3FormulaFormatter_visit( node, ASTNode_getChild(node, 0), sb, settings);

    for (n = 1; n < numChildren; n++)
    {
      L3FormulaFormatter_format(sb, node, settings);
      L3FormulaFormatter_visit( node, ASTNode_getChild(node, n), sb, settings);
    }
  }

  if (group)
  {
    StringBuffer_appendChar(sb, ')');
  }
}
Пример #5
0
/**
 * Since graphviz will interpret identical names as referring to
 * the same node presentation-wise it is better if each function node
 * has a unique name.
 * 
 * Returns the name of the function with the name of the first child
 * prepended
 *
 * THIS COULD BE DONE BETTER
 */
char *
FormulaGraphvizFormatter_FunctionGetUniqueName (const ASTNode_t *node)
{
  char           *s;
  StringBuffer_t *p   = StringBuffer_create(128);
  ASTNodeType_t  type = ASTNode_getType(node);
 
  if (ASTNode_getNumChildren(node) != 0)
  {
	const char* name = ASTNode_getName(ASTNode_getChild(node,0));
	if (name != NULL)
    StringBuffer_append(p, name);
  }
  else
  {
    StringBuffer_append(p, "unknown");
  }

  switch (type)
  {
    case AST_FUNCTION_ARCCOS:
      StringBuffer_append(p, "acos");
      break;

    case AST_FUNCTION_ARCSIN:
      StringBuffer_append(p, "asin");
      break;

    case AST_FUNCTION_ARCTAN:
      StringBuffer_append(p, "atan");
      break;

    case AST_FUNCTION_CEILING:
      StringBuffer_append(p, "ceil");
      break;

    case AST_FUNCTION_LN:
      StringBuffer_append(p, "log");
      break;

    case AST_FUNCTION_POWER:
      StringBuffer_append(p, "pow");
      break;

    default:
      if (ASTNode_getName(node) != NULL)
      {
        StringBuffer_append(p, ASTNode_getName(node));
      }
      break;
  }
  
  s = StringBuffer_toString(p);

  free(p);

  return s;
}
END_TEST


START_TEST (test_SBML_parseFormula_16)
{
  ASTNode_t *r = SBML_parseFormula("foo(1, bar, 2^-3)");
  ASTNode_t *c;


  fail_unless( ASTNode_getType(r) == AST_FUNCTION , NULL );
  fail_unless( !strcmp(ASTNode_getName(r), "foo") , NULL );
  fail_unless( ASTNode_getNumChildren(r) == 3     , NULL );

  c = ASTNode_getChild(r, 0);

  fail_unless( ASTNode_getType       (c) == AST_INTEGER, NULL );
  fail_unless( ASTNode_getInteger    (c) == 1, NULL );
  fail_unless( ASTNode_getNumChildren(c) == 0, NULL );

  c = ASTNode_getChild(r, 1);

  fail_unless( ASTNode_getType(c) == AST_NAME     , NULL );
  fail_unless( !strcmp(ASTNode_getName(c), "bar") , NULL );
  fail_unless( ASTNode_getNumChildren(c) == 0     , NULL );

  c = ASTNode_getChild(r, 2);

  fail_unless( ASTNode_getType       (c) == AST_POWER, NULL );
  fail_unless( ASTNode_getCharacter  (c) == '^', NULL );
  fail_unless( ASTNode_getNumChildren(c) == 2  , NULL );

  c = ASTNode_getLeftChild( ASTNode_getChild(r, 2) );

  fail_unless( ASTNode_getType       (c) == AST_INTEGER, NULL );
  fail_unless( ASTNode_getInteger    (c) == 2, NULL );
  fail_unless( ASTNode_getNumChildren(c) == 0, NULL );

  c = ASTNode_getRightChild( ASTNode_getChild(r, 2) );

  fail_unless( ASTNode_getType       (c) == AST_INTEGER, NULL );
  fail_unless( ASTNode_getInteger    (c) == -3, NULL );
  fail_unless( ASTNode_getNumChildren(c) == 0 , NULL );

  ASTNode_free(r);
}
Пример #7
0
/**
 * Visits the given ASTNode as the function "root(2, x)" and in doing so,
 * formats it as "sqrt(x)" (where x is any subexpression).
 */
void
FormulaFormatter_visitSqrt ( const ASTNode_t *parent,
                             const ASTNode_t *node,
                             StringBuffer_t  *sb )
{
  StringBuffer_append(sb, "sqrt(");
  FormulaFormatter_visit(node, ASTNode_getChild(node, 1), sb);
  StringBuffer_appendChar(sb, ')');
}
Пример #8
0
/**
 * Visits the given ASTNode as the function "root(2, x)" and in doing so,
 * formats it as "sqrt(x)" (where x is any subexpression).
 */
void
L3FormulaFormatter_visitSqrt ( const ASTNode_t *parent,
                               const ASTNode_t *node,
                               StringBuffer_t  *sb, 
                               const L3ParserSettings_t *settings )
{
  StringBuffer_append(sb, "sqrt(");
  L3FormulaFormatter_visit(node, ASTNode_getChild(node, 1), sb, settings);
  StringBuffer_appendChar(sb, ')');
}
Пример #9
0
/**
 * Visits the given ASTNode as a function.  For this node only the
 * traversal is preorder.
 * Writes the function as a directed graph and appends the result
 * to the StringBuffer.
 */
void
FormulaGraphvizFormatter_visitFunction (const ASTNode_t *parent,
                                        const ASTNode_t *node,
                                        StringBuffer_t  *sb )
{
  unsigned int numChildren = ASTNode_getNumChildren(node);
  unsigned int n;
  char         *name;
  char         *uniqueName;
  
  uniqueName = FormulaGraphvizFormatter_getUniqueName(node);
  name       = FormulaGraphvizFormatter_format(node);
  
  StringBuffer_append(sb, uniqueName);
  StringBuffer_append(sb, " [shape=box, label=");
  StringBuffer_append(sb, name);
  StringBuffer_append(sb, "];\n");

  if (parent != NULL) 
  {
    name = FormulaGraphvizFormatter_getUniqueName(node);
    uniqueName = FormulaGraphvizFormatter_getUniqueName(parent);
    
    if(strcmp(name, uniqueName)) 
    {
      StringBuffer_append(sb, uniqueName);
      StringBuffer_append(sb, " -> ");
      StringBuffer_append(sb, name);
      StringBuffer_append(sb, ";\n");
    }
  }

  if (numChildren > 0)
  {
    FormulaGraphvizFormatter_visit( node, ASTNode_getChild(node, 0), sb );
  }

  for (n = 1; n < numChildren; n++)
  {
    FormulaGraphvizFormatter_visit( node, ASTNode_getChild(node, n), sb );
  }

}
Пример #10
0
void
printFunctionDefinition (unsigned int n, const FunctionDefinition_t *fd)
{
  const ASTNode_t *math;
  char *formula;


  if ( FunctionDefinition_isSetMath(fd) )
  {
    printf("FunctionDefinition %d, %s(", n, FunctionDefinition_getId(fd));

    math = FunctionDefinition_getMath(fd);

    /* Print function arguments. */
    if (ASTNode_getNumChildren(math) > 1)
    {
      printf("%s", ASTNode_getName( ASTNode_getLeftChild(math) ));

      for (n = 1; n < ASTNode_getNumChildren(math) - 1; ++n)
      {
        printf(", %s", ASTNode_getName( ASTNode_getChild(math, n) ));
      }
    }

    printf(") := ");

    /* Print function body. */
    if (ASTNode_getNumChildren(math) == 0)
    {
      printf("(no body defined)");
    }
    else
    {
      math    = ASTNode_getChild(math, ASTNode_getNumChildren(math) - 1);
      formula = SBML_formulaToString(math);
      printf("%s\n", formula);
      free(formula);
    }
  }
}
Пример #11
0
/**
 * Visits the given ASTNode as the function "root(2, x)" and in doing so,
 * formats it as "sqrt(x)" (where x is any subexpression).
 * Writes the function as a directed graph and appends the result
 * to the StringBuffer.
 * 
 * A seperate function may not be strictly speaking necessary for graphs
 */
void
FormulaGraphvizFormatter_visitSqrt (const ASTNode_t *parent,
                                    const ASTNode_t *node,
                                    StringBuffer_t  *sb )
{
  char *uniqueName = FormulaGraphvizFormatter_getUniqueName(node);
  char *name       = FormulaGraphvizFormatter_format(node);

  StringBuffer_append(sb, uniqueName);
  StringBuffer_append(sb, " [shape=box, label=");
  StringBuffer_append(sb, name);
  StringBuffer_append(sb, "];\n");

  FormulaGraphvizFormatter_visit(node, ASTNode_getChild(node, 1), sb);
}
Пример #12
0
void post_ev_alter_tree_structure(Model_t *m, ASTNode_t **node_p, ASTNode_t *parent, int child_order){
  ASTNode_t *divide_node, *times_node;
  ASTNode_t *compartment_node;
  ASTNode_t *node, *next_node;
  unsigned int i;
  Species_t *sp;

  node = *node_p;
  for(i=0; i<ASTNode_getNumChildren(node); i++){
    next_node = ASTNode_getChild(node, i);
    post_ev_alter_tree_structure(m, &next_node, *node_p, i);
  }
  if(ASTNode_getType(node) == AST_NAME){
    for(i=0; i<Model_getNumSpecies(m); i++){
      sp = (Species_t*)ListOf_get(Model_getListOfSpecies(m), i);
      if(strcmp(Species_getId(sp), ASTNode_getName(node)) == 0){
        if(!Species_getHasOnlySubstanceUnits(sp) && Compartment_getSpatialDimensions(Model_getCompartmentById(m, Species_getCompartment(sp))) != 0){/* use val/comp in calculation */
          divide_node = ASTNode_createWithType(AST_DIVIDE);
          compartment_node = ASTNode_createWithType(AST_NAME);
          ASTNode_setName(compartment_node, Compartment_getId(Model_getCompartmentById(m, Species_getCompartment(sp))));
          ASTNode_addChild(divide_node, node);
          ASTNode_addChild(divide_node, compartment_node);
          if(parent != NULL){
            ASTNode_replaceChild(parent, child_order, divide_node);
          }else{
            *node_p = divide_node;
          }
          node = *node_p;
          break;
        }else if(Species_getHasOnlySubstanceUnits(sp) && Species_isSetInitialConcentration(sp) && Compartment_getSpatialDimensions(Model_getCompartmentById(m, Species_getCompartment(sp))) != 0){/*  use val*comp in calculation */
          times_node = ASTNode_createWithType(AST_TIMES);
          compartment_node = ASTNode_createWithType(AST_NAME);
          ASTNode_setName(compartment_node, Compartment_getId(Model_getCompartmentById(m, Species_getCompartment(sp))));
          ASTNode_addChild(times_node, node);
          ASTNode_addChild(times_node, compartment_node);
          if(parent != NULL){
            ASTNode_replaceChild(parent, child_order, times_node);
          }else{
            *node_p = times_node;
          }
          node = *node_p;
          break;
        }
      }
    }
  }
  return;
}
Пример #13
0
void pre_ev_alter_tree_structure(ASTNode_t **node_p, ASTNode_t *parent, int child_order, ASTNode_t *delay_math){
  unsigned int i;
  ASTNode_t *node, *next_node, *delay_node;

  node = *node_p;
  for(i=0; i<ASTNode_getNumChildren(node); i++){
    next_node = ASTNode_getChild(node, i);
    pre_ev_alter_tree_structure(&next_node, *node_p, i, delay_math);
  }
  if(ASTNode_getType(node) == AST_NAME){
    delay_node = ASTNode_createWithType(AST_FUNCTION_DELAY);
    ASTNode_addChild(delay_node, node);
    ASTNode_addChild(delay_node, delay_math);
    if(parent != NULL){
      ASTNode_replaceChild(parent, child_order, delay_node);
    }else{
      *node_p = delay_node;
    }
  }
}
Пример #14
0
/**
 * Visits the given ASTNode node.  This function is really just a
 * dispatcher to either SBML_formulaToString_visitFunction() or
 * SBML_formulaToString_visitOther().
 */
void
FormulaFormatter_visit ( const ASTNode_t *parent,
                         const ASTNode_t *node,
                         StringBuffer_t  *sb )
{

  if (ASTNode_isLog10(node))
  {
    FormulaFormatter_visitLog10(parent, node, sb);
  }
  else if (ASTNode_isSqrt(node))
  {
    FormulaFormatter_visitSqrt(parent, node, sb);
  }
  else if (FormulaFormatter_isFunction(node))
  {
    FormulaFormatter_visitFunction(parent, node, sb);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_MINUS, 1))
  {
    FormulaFormatter_visitUMinus(parent, node, sb);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_PLUS, 1) || ASTNode_hasTypeAndNumChildren(node, AST_TIMES, 1))
  {
    FormulaFormatter_visit(node, ASTNode_getChild(node, 0), sb);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_PLUS, 0))
  {
    StringBuffer_appendInt(sb, 0);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_TIMES, 0))
  {
    StringBuffer_appendInt(sb, 1);
  }
  else
  {
    FormulaFormatter_visitOther(parent, node, sb);
  }
}
Пример #15
0
/**
 * The function evalAST(ASTNode_t) evaluates the formula of an
 * Abstract Syntax Tree by simple recursion and returns the result
 * as a double value.
 *
 * If variables (ASTNodeType_t AST_NAME) occur in the formula the user is
 * asked to provide a numerical value.  When evaluating ASTs within an SBML
 * document or simulating an SBML model this node type includes parameters
 * and variables of the model.  Parameters should be retrieved from the
 * SBML file, time and variables from current values of the simulation.
 *
 * Not implemented:
 *
 *  - PIECEWISE, LAMBDA, and the SBML model specific functions DELAY and
 *    TIME and user-defined functions.
 *
 *  - Complex numbers and/or checking for domains of trigonometric and root
 *    functions.
 *
 *  - Checking for precision and rounding errors.
 *
 * The Nodetypes AST_TIME, AST_DELAY and AST_PIECEWISE default to 0.  The
 * SBML DELAY function and unknown functions (SBML user-defined functions)
 * use the value of the left child (first argument to function) or 0 if the
 * node has no children.
 */
double
evalAST(ASTNode_t *n)
{
  int    i;
  double result;
  
  int       childnum = ASTNode_getNumChildren(n);
  ASTNode_t  **child = (ASTNode_t **) malloc(childnum * sizeof(ASTNode_t*));


  for (i = 0; i < childnum; i++)
  {
    child[i] = ASTNode_getChild(n, i);
  }

  switch (ASTNode_getType(n))
  {
  case AST_INTEGER:
    result = (double) ASTNode_getInteger(n);
    break;

  case AST_REAL:
    result = ASTNode_getReal(n);
    break;

  case AST_REAL_E:
    result = ASTNode_getReal(n);
    break;

  case AST_RATIONAL:
    result = ASTNode_getReal(n);
    break;
  
  case AST_NAME:
    {
      char *l;
      double var;
      printf("\n-------------MESSAGE FROM EVALUATION FUNCTION-------------\n");
      printf("Please enter a number for the variable!\n");
      printf("If you do not enter a valid number (empty or characters), the \n");
      printf("evaluation will proceed with a current internal value and the \n");
      printf("result will make no sense.\n");
      printf("%s=",ASTNode_getName(n));
      l = get_line(stdin);
      sscanf(l, "%lf", &var);
      free(l);
      printf("%s = %f\n", ASTNode_getName(n), var);
      printf("-----------------------END MESSAGE--------------------------\n\n");
      result = var;
    }
    break;

  case AST_FUNCTION_DELAY:
    printf("\n-------------MESSAGE FROM EVALUATION FUNCTION-------------\n");
    printf("Delays can only be evaluated during a time series simulation.\n");
    printf("The value of the first child (ie. the first argument to the function)\n");
    printf("is used for this evaluation. If the function node has no children the\n");
    printf("value defaults to 0.\n");
    printf("-----------------------END MESSAGE--------------------------\n\n");
    if(i>0)
      result = evalAST(child[0]);
    else
      result = 0.0;
    break;

  case AST_NAME_TIME:
    printf("\n-------------MESSAGE FROM EVALUATION FUNCTION-------------\n");
    printf("The time can only be evaluated during a time series simulation.\n");
    printf("The value of defaults to 0\n");
    printf("-----------------------END MESSAGE--------------------------\n\n");
    result = 0.0;
    break;

  case AST_CONSTANT_E:
    /* exp(1) is used to adjust exponentiale to machine precision */
    result = exp(1);
    break;

  case AST_CONSTANT_FALSE:
    result = 0.0;
    break;

  case AST_CONSTANT_PI:
    /* pi = 4 * atan 1  is used to adjust Pi to machine precision */
    result = 4.*atan(1.);
    break;

  case AST_CONSTANT_TRUE:
    result = 1.0;
    break;

  case AST_PLUS:
    result = evalAST(child[0]) + evalAST(child[1]);
    break;

  case AST_MINUS:
    if(childnum==1)
      result = - (evalAST(child[0]));
    else
      result = evalAST(child[0]) - evalAST(child[1]);
    break;

  case AST_TIMES:
    result = evalAST(child[0]) * evalAST(child[1]) ;
    break;

  case AST_DIVIDE:
    result = evalAST(child[0]) / evalAST(child[1]);
    break;

  case AST_POWER:
    result = pow(evalAST(child[0]),evalAST(child[1]));
    break;

  case AST_LAMBDA:
    printf("\n-------------MESSAGE FROM EVALUATION FUNCTION-------------\n");
    printf("This function is not implemented yet.\n");
    printf("The value defaults to 0.\n");
    printf("-----------------------END MESSAGE--------------------------\n\n");
    result = 0.0;
    break;

  case AST_FUNCTION:
    printf("\n-------------MESSAGE FROM EVALUATION FUNCTION-------------\n");
    printf("This function is not known.\n");
    printf("Within an SBML document new functions can be defined by the user or \n");
    printf("application. The value of the first child (ie. the first argument to \n");
    printf("the function) is used for this evaluation. If the function node has\n");
    printf("no children the value defaults to 0.\n");
    printf("-----------------------END MESSAGE--------------------------\n\n");
    if(childnum>0)
      result = evalAST(child[0]);
    else
      result = 0.0;
    break;

  case AST_FUNCTION_ABS:
    result = (double) fabs(evalAST(child[0]));
    break;

  case AST_FUNCTION_ARCCOS:
    result = acos(evalAST(child[0])) ;
    break;

  case AST_FUNCTION_ARCCOSH:
#ifndef WIN32
    result = acosh(evalAST(child[0]));
#else
	result = log(evalAST(child[0]) + SQR(evalAST(child[0]) * evalAST(child[0]) - 1.));
#endif
    break;
  case AST_FUNCTION_ARCCOT:
    /* arccot x =  arctan (1 / x) */
    result = atan(1./ evalAST(child[0]));
    break;

  case AST_FUNCTION_ARCCOTH:
    /* arccoth x = 1/2 * ln((x+1)/(x-1)) */
    result = ((1./2.)*log((evalAST(child[0])+1.)/(evalAST(child[0])-1.)) );
    break;

  case AST_FUNCTION_ARCCSC:
    /* arccsc(x) = Arctan(1 / sqrt((x - 1)(x + 1))) */
    result = atan( 1. / SQRT( (evalAST(child[0])-1.)*(evalAST(child[0])+1.) ) );
    break;

  case AST_FUNCTION_ARCCSCH:
    /* arccsch(x) = ln((1 + sqrt(1 + x^2)) / x) */
    result = log((1.+SQRT((1+SQR(evalAST(child[0]))))) /evalAST(child[0]));
    break;

  case AST_FUNCTION_ARCSEC:
    /* arcsec(x) = arctan(sqrt((x - 1)(x + 1))) */
    result = atan( SQRT( (evalAST(child[0])-1.)*(evalAST(child[0])+1.) ) );
    break;

  case AST_FUNCTION_ARCSECH:
    /* arcsech(x) = ln((1 + sqrt(1 - x^2)) / x) */
    result = log((1.+pow((1-SQR(evalAST(child[0]))),0.5))/evalAST(child[0]));
    break;

  case AST_FUNCTION_ARCSIN:
    result = asin(evalAST(child[0]));
    break;
  case AST_FUNCTION_ARCSINH:
#ifndef WIN32
    result = asinh(evalAST(child[0]));
#else
	result = log(evalAST(child[0]) + SQR(evalAST(child[0]) * evalAST(child[0]) + 1.));
#endif
    break;

  case AST_FUNCTION_ARCTAN:
    result = atan(evalAST(child[0]));
    break;
  case AST_FUNCTION_ARCTANH:
#ifndef WIN32
    result = atanh(evalAST(child[0]));
#else
	result = log((1. / evalAST(child[0]) + 1.) / (1. / evalAST(child[0]) - 1.)) / 2.;
#endif
    break;

  case AST_FUNCTION_CEILING:
    result = ceil(evalAST(child[0]));
    break;

  case AST_FUNCTION_COS:
    result = cos(evalAST(child[0]));
    break;
  case AST_FUNCTION_COSH:
    result = cosh(evalAST(child[0]));
    break;

  case AST_FUNCTION_COT:
    /* cot x = 1 / tan x */
    result = (1./tan(evalAST(child[0])));
    break;
  case AST_FUNCTION_COTH:
    /* coth x = cosh x / sinh x */
    result = cosh(evalAST(child[0])) / sinh(evalAST(child[0]));
    break;
  case AST_FUNCTION_CSC:
    /* csc x = 1 / sin x */
    result = (1./sin(evalAST(child[0])));
    break;

  case AST_FUNCTION_CSCH:
    /* csch x = 1 / cosh x  */
    result = (1./cosh(evalAST(child[0])));
    break;

  case AST_FUNCTION_EXP:
    result = exp(evalAST(child[0]));
    break;

  case AST_FUNCTION_FACTORIAL:
    {
      printf("\n-------------MESSAGE FROM EVALUATION FUNCTION-------------\n");
      printf("The factorial is only implemented for integer values. If a floating\n");
      printf("point number is passed, the floor value is used for calculation!\n");
      printf("-----------------------END MESSAGE--------------------------\n\n");
      i = (int)floor(evalAST(child[0]));
      for(result=1;i>1;--i)
        result *= i;
    }
    break;

  case AST_FUNCTION_FLOOR:
    result = floor(evalAST(child[0]));
    break;

  case AST_FUNCTION_LN:
    result = log(evalAST(child[0]));
    break;

  case AST_FUNCTION_LOG:
    result = log10(evalAST(child[0]));
    break;

  case AST_FUNCTION_PIECEWISE:
    printf("\n-------------MESSAGE FROM EVALUATION FUNCTION-------------\n");
    printf("This function is not implemented yet.\n");
    printf("The value defaults to 0.\n");
    printf("-----------------------END MESSAGE--------------------------\n\n");
    result = 0.0;
    break;

  case AST_FUNCTION_POWER:
    result = pow(evalAST(child[0]),evalAST(child[1]));
    break;

  case AST_FUNCTION_ROOT:
    result = pow(evalAST(child[1]),(1./evalAST(child[0])));
    break;

  case AST_FUNCTION_SEC:
    /* sec x = 1 / cos x */
    result = 1./cos(evalAST(child[0]));
    break;

  case AST_FUNCTION_SECH:
    /* sech x = 1 / sinh x */
    result = 1./sinh(evalAST(child[0]));
    break;

  case AST_FUNCTION_SIN:
    result = sin(evalAST(child[0]));
    break;

  case AST_FUNCTION_SINH:
    result = sinh(evalAST(child[0]));
    break;

  case AST_FUNCTION_TAN:
    result = tan(evalAST(child[0]));
    break;

  case AST_FUNCTION_TANH:
    result = tanh(evalAST(child[0]));
    break;

  case AST_LOGICAL_AND:
    result = (double) ((evalAST(child[0])) && (evalAST(child[1])));
    break;

  case AST_LOGICAL_NOT:
    result = (double) (!(evalAST(child[0])));
    break;

  case AST_LOGICAL_OR:
    result = (double) ((evalAST(child[0])) || (evalAST(child[1])));
    break;

  case AST_LOGICAL_XOR:
    result = (double) ((!(evalAST(child[0])) && (evalAST(child[1])))
                       || ((evalAST(child[0])) &&  !(evalAST(child[1]))));
    break;

  case AST_RELATIONAL_EQ :
    result = (double) ((evalAST(child[0])) == (evalAST(child[1])));
    break;

  case AST_RELATIONAL_GEQ:
    result = (double) ((evalAST(child[0])) >= (evalAST(child[1])));
    break;

  case AST_RELATIONAL_GT:
    result = (double) ((evalAST(child[0])) > (evalAST(child[1])));
    break;

  case AST_RELATIONAL_LEQ:
    result = (double) ((evalAST(child[0])) <= (evalAST(child[1])));
    break;

  case AST_RELATIONAL_LT :
    result = (double) ((evalAST(child[0])) < (evalAST(child[1])));
    break;

  default:
    result = 0;
    break;
  }

  free(child);

  return result;
}
Пример #16
0
void ev_alter_tree_structure(Model_t *m, ASTNode_t **node_p, ASTNode_t *parent, int child_order, copied_AST *cp_AST){
  ASTNode_t *zero_node;
  ASTNode_t *node, *next_node;
  ASTNode_t *pc_eq, *pc_cd, *times_node, *and_node, *not_node;
  unsigned int i, j;
  int p;
  ASTNode_t *arg_node_list[MAX_ARG_NUM];
  unsigned int arg_node_num;
  FunctionDefinition_t *fd;
  ASTNode_t *fd_arg;
  ASTNode_t *fd_body;

  node = *node_p;
  for(i=0; i<ASTNode_getNumChildren(node); i++){
    next_node = ASTNode_getChild(node, i);
    if(ASTNode_getNumChildren(node) == 1 && ASTNode_getType(node) == AST_MINUS){
      zero_node = ASTNode_create();
      ASTNode_setType(zero_node, AST_REAL);
      ASTNode_setReal(zero_node, 0);
      ASTNode_replaceChild(node, 0, zero_node);
      ASTNode_addChild(*node_p, next_node);
    }else{
      ev_alter_tree_structure(m, &next_node, *node_p, i, cp_AST);
    }
  }
  if(ASTNode_getType(node) == AST_FUNCTION){
    arg_node_num = ASTNode_getNumChildren(node);
    for(i=0; i<arg_node_num; i++){
      arg_node_list[i] = ASTNode_getChild(node, i);
    }
    for(i=0; i<Model_getNumFunctionDefinitions(m); i++){
      fd = (FunctionDefinition_t*)ListOf_get(Model_getListOfFunctionDefinitions(m), i);
      fd_body = (ASTNode_t*)FunctionDefinition_getBody(fd);
      if(strcmp(FunctionDefinition_getId(fd), ASTNode_getName(node)) == 0){
        fd_body = ASTNode_deepCopy(fd_body);
        cp_AST->ast[cp_AST->num_of_copied_AST++] = fd_body;
        for(j=0; j<FunctionDefinition_getNumArguments(fd); j++){
          fd_arg = (ASTNode_t*)FunctionDefinition_getArgument(fd, j);
          ASTNode_replaceArgument(fd_body, (char*)ASTNode_getName(fd_arg), arg_node_list[j]);
        }
        /* check_AST(fd_body, NULL); */
        if(parent != NULL){
          ASTNode_replaceChild(parent, child_order, fd_body);
        }else{
          *node_p = fd_body;
        }
        node = *node_p;
        break;
      }
    }
  }
  if(ASTNode_getType(node) == AST_FUNCTION_PIECEWISE){
    ASTNode_setType(node, AST_PLUS);
    ASTNode_setName(node, NULL);
    times_node = ASTNode_createWithType(AST_TIMES);
    pc_eq = ASTNode_getRightChild(node);
    ASTNode_addChild(times_node, pc_eq);
    if(ASTNode_getNumChildren(node) > 3){
      and_node = ASTNode_createWithType(AST_LOGICAL_AND);
      ASTNode_addChild(times_node, and_node);
      for(p=(int)ASTNode_getNumChildren(node)-2; p >= 1; p = p-2){
        pc_cd = ASTNode_getChild(node, p);
        not_node = ASTNode_createWithType(AST_LOGICAL_NOT);
        ASTNode_addChild(not_node, pc_cd);
        ASTNode_addChild(and_node, not_node);
      }
      ASTNode_reduceToBinary(and_node);
    }else{
      pc_cd = ASTNode_getChild(node, 1);
      not_node = ASTNode_createWithType(AST_LOGICAL_NOT);
      ASTNode_addChild(not_node, pc_cd);
      ASTNode_addChild(times_node, not_node);
    }
    ASTNode_replaceChild(node, ASTNode_getNumChildren(node)-1, times_node);
    for(p=ASTNode_getNumChildren(node)-2; p >= 1; p = p-2){
      times_node = ASTNode_createWithType(AST_TIMES);
      pc_eq = ASTNode_getChild(node, p-1);
      pc_cd = ASTNode_getChild(node, p);
      ASTNode_addChild(times_node, pc_eq);
      ASTNode_addChild(times_node, ASTNode_deepCopy(pc_cd));
      ASTNode_removeChild(node, p);
      ASTNode_replaceChild(node ,p-1, times_node);
    }
    ASTNode_reduceToBinary(node);
  }
  return;
}
Пример #17
0
void printReactions(Model_t *m, FILE *f)
{
  
  int i,j,k;
  Reaction_t *r;
  SpeciesReference_t *sref;
  KineticLaw_t *kl;
  Rule_t *rl;
  AssignmentRule_t *asr;
  AlgebraicRule_t *alr;
  RateRule_t *rr;
  Event_t *e;
  EventAssignment_t *ea;
  Parameter_t *p;
  FunctionDefinition_t *fd;
  SBMLTypeCode_t type;
  const ASTNode_t *math;

  math = NULL;
  
  fprintf(f, "\n");
  for(i=0;i<Model_getNumParameters(m);i++){
    if(i==0)
      fprintf(f, "# Global parameters:\n");
    p = Model_getParameter(m,i);
    if(Parameter_isSetId(p))
      fprintf(f, "%s ",  Parameter_getId(p));
    if(Parameter_isSetName(p))
      fprintf(f, "(%s) ", Parameter_getName(p));
    if(Parameter_isSetValue(p))
      fprintf(f, "= %g; ", Parameter_getValue(p));
    if(Parameter_isSetUnits(p))
      fprintf(f, "[%s]; ", Parameter_getUnits(p));
    if(!Parameter_getConstant(p))
      fprintf(f, "(variable);");
    fprintf(f, "\n");
    
    if ( i==Model_getNumParameters(m)-1 )
      fprintf(f, "\n");
  }

  fprintf(f, "# Reactions:\n");
  for ( i=0; i<Model_getNumReactions(m); i++ ) {    
    r = Model_getReaction(m,i);
  
    fprintf(f, "%s: %s",
	   Reaction_isSetName(r) ? Reaction_getName(r) : Reaction_getId(r),
	   Reaction_getFast(r) ? "(fast)" : "");
    for ( k=0; k<Reaction_getNumReactants(r); k++ ) {
      sref = Reaction_getReactant(r,k);

      if ( SpeciesReference_isSetStoichiometryMath(sref) )	
	fprintf(f, "%s ",
		SBML_formulaToString(\
		SpeciesReference_getStoichiometryMath(sref)));
      else 
	if ( SpeciesReference_getStoichiometry(sref) != 1. )
	  fprintf(f, "%g ",  SpeciesReference_getStoichiometry(sref));
	
      fprintf(f, "%s", SpeciesReference_getSpecies(sref));
      if(k+1<Reaction_getNumReactants(r))
	fprintf(f, "%s", " + ");
    }
    
    fprintf(f, "%s", Reaction_getReversible(r) ? " <-> " : " -> ");
    for ( k=0; k<Reaction_getNumProducts(r); k++ ) {
      sref = Reaction_getProduct(r,k);
      if ( SpeciesReference_isSetStoichiometryMath(sref) )
	fprintf(f, "%s ",
	       SBML_formulaToString(\
		   SpeciesReference_getStoichiometryMath(sref)));
      else
	if ( SpeciesReference_getStoichiometry(sref) != 1. )
	  fprintf(f, "%g ", SpeciesReference_getStoichiometry(sref));
      
      fprintf(f, "%s", SpeciesReference_getSpecies(sref));
      if(k+1<Reaction_getNumProducts(r))
	fprintf(f, "%s", " + ");
    }
    fprintf(f, ";  ");
    if(Reaction_isSetKineticLaw(r)){
      kl = Reaction_getKineticLaw(r);
      math = KineticLaw_getMath(kl);
      fprintf(f, "%s;", SBML_formulaToString(math));
      for(k=0;k<KineticLaw_getNumParameters(kl);k++){
	
	p = KineticLaw_getParameter(kl,k);
	fprintf(f, " %s",  Parameter_getId(p));
	if(Parameter_isSetName(p))
	  fprintf(f, " (%s)", Parameter_getName(p));
	if(Parameter_isSetValue(p))
	  fprintf(f, " = %g", Parameter_getValue(p));
	if(Parameter_isSetUnits(p))
	  fprintf(f, " [%s]", Parameter_getUnits(p));
	if ( !Parameter_getConstant(p) )
	  fprintf(f, " (variable)");
	fprintf(f, ";");
      }
     /*  fprintf(f, "\n"); */
    }else
      fprintf(f, "#   no rate law is set for this reaction.");
    fprintf(f, "\n");
  }
    
  for(i=0;i<Model_getNumRules(m);i++){
    rl = Model_getRule(m,i);
    if ( i == 0 ) {
      fprintf(f, "# Rules:\n");
    }
    type = SBase_getTypeCode((SBase_t *)rl);
     
     
    if ( type == SBML_RATE_RULE ) {
      rr =  (RateRule_t *) rl;
      fprintf(f, " rateRule:       d%s/dt = ", RateRule_getVariable(rr));
    }
    if ( type == SBML_ALGEBRAIC_RULE ) {
      alr = (AlgebraicRule_t *) rl;
      fprintf(f, " algebraicRule:       0 = ");
    }
    if ( type == SBML_ASSIGNMENT_RULE ) {
      asr = (AssignmentRule_t *) rl;
      fprintf(f, " assignmentRule (%s): %s = ",
	     RuleType_toString(AssignmentRule_getType(asr)),
	     AssignmentRule_getVariable(asr));
    }
    if(!Rule_isSetMath(rl)){
      if(Rule_isSetFormula(rl)){
	Rule_setMathFromFormula(rl);
	
      }
    }
    if(Rule_isSetMath(rl))
      fprintf(f, "%s\n", SBML_formulaToString(Rule_getMath(rl)));
	     
  }
  fprintf(f, "\n");

  for(i=0;i<Model_getNumEvents(m);i++){
    if(i==0)
      fprintf(f, "# Events:\n");
    e = Model_getEvent(m,i);
    if(Event_isSetId(e))
      fprintf(f, "%s: ", Event_getId(e));
    if(Event_isSetName(e))
      fprintf(f, "(%s) ", Event_getName(e));   
    if(Event_isSetTrigger(e)) {
      math = Event_getTrigger(e);
      fprintf(f, "trigger: %s\n", SBML_formulaToString(math));
    }
    if(Event_isSetDelay(e))
      fprintf(f, "delay: %s;\n", SBML_formulaToString(Event_getDelay(e)));
    if(Event_isSetTimeUnits(e))
      fprintf(f, "time Units: %s;\n", Event_getTimeUnits(e));
    for(k=0;k<Event_getNumEventAssignments(e);k++){      
      ea = Event_getEventAssignment(e,k);
      if(EventAssignment_isSetVariable(ea))
	fprintf(f, "  event:  %s = %s;\n",
	       EventAssignment_getVariable(ea),
	       EventAssignment_isSetMath(ea) ?
	       SBML_formulaToString(EventAssignment_getMath(ea)) :
	       "# no math set;\n");
    }

    if(i==Model_getNumEvents(m)-1)
       fprintf(f, "\n"); 
  }  


  for ( i=0; i<Model_getNumFunctionDefinitions(m); i++ ) {

    if ( i==0 ) fprintf(f, "# Functions:\n");

    fd = Model_getFunctionDefinition(m,i);
    if ( FunctionDefinition_isSetName(fd) )
      fprintf(f, "%s: ", FunctionDefinition_getName(fd));
    if(FunctionDefinition_isSetId(fd) && FunctionDefinition_isSetMath(fd)){
      fprintf(f, "%s( ", FunctionDefinition_getId(fd));
      math = FunctionDefinition_getMath(fd);
	for(j=0;j<ASTNode_getNumChildren(math)-1;j++){
	  fprintf(f, "%s", SBML_formulaToString(ASTNode_getChild(math, j)));
	  if(j<ASTNode_getNumChildren(math)-2)
	    fprintf(f, ", ");
	  if(j==ASTNode_getNumChildren(math)-2)
	    fprintf(f, ") = ");
	}
      fprintf(f, "%s;", SBML_formulaToString(ASTNode_getRightChild(math)));
    }
    fprintf(f, "\n");
  } 
  
}
Пример #18
0
/**
 * Since graphviz will interpret identical names as referring to
 * the same node presentation-wise it is better if each function node
 * has a unique name.
 * 
 * Returns the name of the operator with the name of the first child
 * prepended
 *
 * THIS COULD BE DONE BETTER
 */
char *
FormulaGraphvizFormatter_OperatorGetUniqueName (const ASTNode_t *node)
{
  char           *s;
  char           number[10];
  StringBuffer_t *p   = StringBuffer_create(128);
  ASTNodeType_t  type = ASTNode_getType(node);
  
  if (FormulaGraphvizFormatter_isFunction(ASTNode_getChild(node,0))
    || ASTNode_isOperator(ASTNode_getChild(node,0))) 
  {
    StringBuffer_append(p, "func");
  }
  else
  {
    if (ASTNode_isInteger(ASTNode_getChild(node, 0)))
    {
      sprintf(number, "%d", (int)ASTNode_getInteger(ASTNode_getChild(node, 0)));
      StringBuffer_append(p, number);
    }
    else if (ASTNode_isReal(ASTNode_getChild(node, 0)))
    {
      sprintf(number, "%ld", ASTNode_getNumerator(ASTNode_getChild(node, 0)));
      StringBuffer_append(p, number);
    }
    else
    {
      StringBuffer_append(p, ASTNode_getName(ASTNode_getChild(node,0)));
    }
  }

  switch (type)
  {
    case AST_TIMES:
      StringBuffer_append(p,  "times");
      break;

    case AST_DIVIDE:
      StringBuffer_append(p,  "divide");
      break;

    case AST_PLUS:
      StringBuffer_append(p,  "plus");
      break;

    case AST_MINUS:
      StringBuffer_append(p,  "minus");
      break;

    case AST_POWER:
      StringBuffer_append(p,  "power");
      break;

    default:
      StringBuffer_appendChar(p, ASTNode_getCharacter(node));
      break;
  }
  
  s = StringBuffer_toString(p);

  free(p);

  return s;
}
Пример #19
0
void check_AST(ASTNode_t* node, ASTNode_t* parent) {
    unsigned int i;
    int type;
    ASTNode_t *checker;
    if(node == NULL) {
        return;
    }
    checker = parent;
    for(i=0; i<ASTNode_getNumChildren(node); i++) {
        parent = node;
        check_AST(ASTNode_getChild(node, i), parent);
    }
    type = ASTNode_getType(node);
    switch(type) {
    case AST_PLUS:
        TRACE(("+ "));
        break;
    case AST_MINUS:
        TRACE(("- "));
        break;
    case AST_TIMES:
        TRACE(("* "));
        break;
    case AST_DIVIDE:
        TRACE(("/ "));
        break;
    case AST_POWER:
        TRACE(("pow "));
        break;
    case AST_INTEGER:
        TRACE(("integer(%ld) ", ASTNode_getInteger(node)));
        break;
    case AST_REAL:
        TRACE(("real(%lf) ", ASTNode_getReal(node)));
        break;
    case AST_REAL_E:
        TRACE(("real_E "));
        break;
    case AST_RATIONAL:
        TRACE(("rational "));
        break;
    case AST_NAME:
        TRACE(("name(%s) ", ASTNode_getName(node)));
        break;
    case AST_NAME_AVOGADRO:
        TRACE(("avogadro "));
        break;
    case AST_NAME_TIME:
        TRACE(("time "));
        break;
    case AST_CONSTANT_E:
        TRACE(("constant "));
        break;
    case AST_CONSTANT_FALSE:
        TRACE(("constant_false "));
        break;
    case AST_CONSTANT_PI:
        TRACE(("pi "));
        break;
    case AST_CONSTANT_TRUE:
        TRACE(("constant_true "));
        break;
    case AST_LAMBDA:
        TRACE(("lambda "));
        break;
    case AST_FUNCTION:
        TRACE(("function(%s) ", ASTNode_getName(node)));
        break;
    case AST_FUNCTION_ABS:
        TRACE(("abs "));
        break;
    case AST_FUNCTION_ARCCOS:
        TRACE(("arccos "));
        break;
    case AST_FUNCTION_ARCCOSH:
        TRACE(("arccosh "));
        break;
    case AST_FUNCTION_ARCCOT:
        TRACE(("arccot "));
        break;
    case AST_FUNCTION_ARCCOTH:
        TRACE(("arccoth "));
        break;
    case AST_FUNCTION_ARCCSC:
        TRACE(("arccsc "));
        break;
    case AST_FUNCTION_ARCCSCH:
        TRACE(("arccsch "));
        break;
    case AST_FUNCTION_ARCSEC:
        TRACE(("arcsec "));
        break;
    case AST_FUNCTION_ARCSECH:
        TRACE(("arcsech "));
        break;
    case AST_FUNCTION_ARCSIN:
        TRACE(("arcsin "));
        break;
    case AST_FUNCTION_ARCSINH:
        TRACE(("arcsinh "));
        break;
    case AST_FUNCTION_ARCTAN:
        TRACE(("arctan "));
        break;
    case AST_FUNCTION_ARCTANH:
        TRACE(("arctanh "));
        break;
    case AST_FUNCTION_CEILING:
        TRACE(("ceil "));
        break;
    case AST_FUNCTION_COS:
        TRACE(("cos "));
        break;
    case AST_FUNCTION_COSH:
        TRACE(("cosh "));
        break;
    case AST_FUNCTION_COT:
        TRACE(("cot "));
        break;
    case AST_FUNCTION_COTH:
        TRACE(("coth "));
        break;
    case AST_FUNCTION_CSC:
        TRACE(("csc "));
        break;
    case AST_FUNCTION_CSCH:
        TRACE(("csch "));
        break;
    case AST_FUNCTION_DELAY:
        TRACE(("delay "));
        break;
    case AST_FUNCTION_EXP:
        TRACE(("exp "));
        break;
    case AST_FUNCTION_FACTORIAL:
        TRACE(("! "));
        break;
    case AST_FUNCTION_FLOOR:
        TRACE(("floor "));
        break;
    case AST_FUNCTION_LN:
        TRACE(("ln "));
        break;
    case AST_FUNCTION_LOG:
        TRACE(("log10 "));
        break;
    case AST_FUNCTION_PIECEWISE:
        TRACE(("piecewise "));
        break;
    case AST_FUNCTION_POWER:
        TRACE(("f_pow "));
        break;
    case AST_FUNCTION_ROOT:
        TRACE(("sqrt "));
        break;
    case AST_FUNCTION_SEC:
        TRACE(("sec "));
        break;
    case AST_FUNCTION_SECH:
        TRACE(("sech "));
        break;
    case AST_FUNCTION_SIN:
        TRACE(("sin "));
        break;
    case AST_FUNCTION_SINH:
        TRACE(("sinh "));
        break;
    case AST_FUNCTION_TAN:
        TRACE(("tan "));
        break;
    case AST_FUNCTION_TANH:
        TRACE(("tanh "));
        break;
    case AST_LOGICAL_AND:
        TRACE(("and "));
        break;
    case AST_LOGICAL_NOT:
        TRACE(("not "));
        break;
    case AST_LOGICAL_OR:
        TRACE(("or "));
        break;
    case AST_LOGICAL_XOR:
        TRACE(("xor "));
        break;
    case AST_RELATIONAL_EQ:
        TRACE(("eq "));
        break;
    case AST_RELATIONAL_GEQ:
        TRACE(("geq "));
        break;
    case AST_RELATIONAL_GT:
        TRACE(("gt "));
        break;
    case AST_RELATIONAL_LEQ:
        TRACE(("leq "));
        break;
    case AST_RELATIONAL_LT:
        TRACE(("lt "));
        break;
    case AST_RELATIONAL_NEQ:
        TRACE(("neq "));
        break;
    case AST_UNKNOWN:
        TRACE(("unknown "));
        break;
    }
    if(checker == NULL) {
        TRACE(("\n\n"));
    }
}
Пример #20
0
/* Used by getL3Precedence and other functions below.
 */
int isTranslatedModulo (const ASTNode_t* node)
{
  const ASTNode_t* child;
  const ASTNode_t* c2;
  const ASTNode_t* x;
  const ASTNode_t* y;
  //In l3v2 there may be an actual 'modulo' ASTNode, but for now,
  // it's all mimicked by the piecewise function:
  // piecewise(x - y * ceil(x / y), xor(x < 0, y < 0), x - y * floor(x / y))

  if (ASTNode_getType(node) != AST_FUNCTION_PIECEWISE) return 0;
  if (ASTNode_getNumChildren(node) != 3) return 0;

  //x - y * ceil(x/y)
  child = ASTNode_getChild(node, 0);
  if (ASTNode_getType(child) != AST_MINUS) return 0;
  if (ASTNode_getNumChildren(child) != 2) return 0;
  x  = ASTNode_getChild(child, 0);

  c2 = ASTNode_getChild(child, 1);
  if (ASTNode_getType(c2) != AST_TIMES) return 0;
  if (ASTNode_getNumChildren(c2) != 2) return 0;
  y = ASTNode_getChild(c2, 0);
  c2 = ASTNode_getChild(c2, 1);
  if (ASTNode_getType(c2) != AST_FUNCTION_CEILING) return 0;
  if (ASTNode_getNumChildren(c2) != 1) return 0;
  c2 = ASTNode_getChild(c2, 0);
  if (ASTNode_getType(c2) != AST_DIVIDE) return 0;
  if (ASTNode_getNumChildren(c2) != 2) return 0;
  if (!equals(x, ASTNode_getChild(c2, 0))) return 0;
  if (!equals(y, ASTNode_getChild(c2, 1))) return 0;

  //xor(x<0, y<0)
  child = ASTNode_getChild(node, 1);
  if (ASTNode_getType(child) != AST_LOGICAL_XOR) return 0;
  if (ASTNode_getNumChildren(child) != 2) return 0;
  c2 = ASTNode_getChild(child, 0);
  if (ASTNode_getType(c2) != AST_RELATIONAL_LT) return 0;
  if (ASTNode_getNumChildren(c2) != 2) return 0;
  if (!equals(x, ASTNode_getChild(c2, 0))) return 0;
  if (ASTNode_getType(ASTNode_getChild(c2, 1)) != AST_INTEGER) return 0;
  if (ASTNode_getInteger(ASTNode_getChild(c2, 1)) != 0) return 0;
  c2 = ASTNode_getChild(child, 1);
  if (ASTNode_getType(c2) != AST_RELATIONAL_LT) return 0;
  if (ASTNode_getNumChildren(c2) != 2) return 0;
  if (!equals(y, ASTNode_getChild(c2, 0))) return 0;
  if (ASTNode_getType(ASTNode_getChild(c2, 1)) != AST_INTEGER) return 0;
  if (ASTNode_getInteger(ASTNode_getChild(c2, 1)) != 0) return 0;

  //x - y * floor(x/y)
  child = ASTNode_getChild(node, 2);
  if (ASTNode_getType(child) != AST_MINUS) return 0;
  if (ASTNode_getNumChildren(child) != 2) return 0;
  if (!equals(x, ASTNode_getChild(child, 0))) return 0;

  c2 = ASTNode_getChild(child, 1);
  if (ASTNode_getType(c2) != AST_TIMES) return 0;
  if (ASTNode_getNumChildren(c2) != 2) return 0;
  if (!equals(y, ASTNode_getChild(c2, 0))) return 0;
  c2 = ASTNode_getChild(c2, 1);
  if (ASTNode_getType(c2) != AST_FUNCTION_FLOOR) return 0;
  if (ASTNode_getNumChildren(c2) != 1) return 0;
  c2 = ASTNode_getChild(c2, 0);
  if (ASTNode_getType(c2) != AST_DIVIDE) return 0;
  if (ASTNode_getNumChildren(c2) != 2) return 0;
  if (!equals(x, ASTNode_getChild(c2, 0))) return 0;
  if (!equals(y, ASTNode_getChild(c2, 1))) return 0;

  return 1;
}