Esempio n. 1
0
END_TEST


START_TEST (test_FunctionDefinition_getArguments)
{
  const ASTNode_t *math; 

  ASTNode_t* math1 = SBML_parseFormula("lambda(x, y, x^y)");
  FunctionDefinition_setMath(FD, math1 );
  ASTNode_free(math1);

  fail_unless( FunctionDefinition_getNumArguments(FD) == 2 );


  math = FunctionDefinition_getArgument(FD, 0);

  fail_unless( math != NULL                        );
  fail_unless( ASTNode_isName(math)                );
  fail_unless( !strcmp(ASTNode_getName(math), "x") );
  fail_unless( ASTNode_getNumChildren(math) == 0   );

  math = FunctionDefinition_getArgument(FD, 1);

  fail_unless( math != NULL                        );
  fail_unless( ASTNode_isName(math)                );
  fail_unless( !strcmp(ASTNode_getName(math), "y") );
  fail_unless( ASTNode_getNumChildren(math) == 0   );

  fail_unless( FunctionDefinition_getArgument(FD, 0) ==
               FunctionDefinition_getArgumentByName(FD, "x") );

  fail_unless( FunctionDefinition_getArgument(FD, 1) ==
               FunctionDefinition_getArgumentByName(FD, "y") );
}
END_TEST


START_TEST (test_SBML_parseFormula_15)
{
  ASTNode_t *r = SBML_parseFormula("foo(1, bar)");
  ASTNode_t *c;


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

  c = ASTNode_getLeftChild(r);

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

  c = ASTNode_getRightChild(r);

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

  ASTNode_free(r);
}
Esempio n. 3
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_12)
{
  ASTNode_t *r = SBML_parseFormula("2 * foo^bar + 3.0");
  ASTNode_t *c;


  fail_unless( ASTNode_getType       (r) == AST_PLUS, NULL );
  fail_unless( ASTNode_getCharacter  (r) == '+', NULL );
  fail_unless( ASTNode_getNumChildren(r) == 2  , NULL );

  c = ASTNode_getLeftChild(r);

  fail_unless( ASTNode_getType       (c) == AST_TIMES, NULL );
  fail_unless( ASTNode_getCharacter  (c) == '*', NULL );
  fail_unless( ASTNode_getNumChildren(c) == 2  , NULL );

  c = ASTNode_getRightChild(r);

  fail_unless( ASTNode_getType       (c) == AST_REAL, NULL );
  fail_unless( ASTNode_getReal       (c) == 3.0, NULL );
  fail_unless( ASTNode_getNumChildren(c) == 0  , NULL );

  c = ASTNode_getLeftChild( ASTNode_getLeftChild(r) );

  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_getLeftChild(r) );

  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_getRightChild( ASTNode_getLeftChild(r) ) );

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

  c = ASTNode_getRightChild( ASTNode_getRightChild( ASTNode_getLeftChild(r) ) );

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

  ASTNode_free(r);
}
Esempio n. 5
0
/**
 * Formats the given ASTNode as a directed graph function name and returns the
 * result as a string.
 */
char *
FormulaGraphvizFormatter_formatFunction (const ASTNode_t *node)
{
  char           *s;
  StringBuffer_t *p   = StringBuffer_create(128);
  ASTNodeType_t  type = ASTNode_getType(node);

  switch (type)
  {
    case AST_FUNCTION_ARCCOS:
      s =  "acos";
      break;

    case AST_FUNCTION_ARCSIN:
      s =  "asin";
      break;

    case AST_FUNCTION_ARCTAN:
      s =  "atan";
      break;

    case AST_FUNCTION_CEILING:
      s =  "ceil";
      break;

    case AST_FUNCTION_LN:
      s =  "log";
      break;

    case AST_FUNCTION_POWER:
      s =  "pow";
      break;

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

  free(p);

  return s;
}
END_TEST


START_TEST (test_SBML_parseFormula_5)
{
  ASTNode_t *r = SBML_parseFormula("1 + foo");
  ASTNode_t *c;



  fail_unless( ASTNode_getType       (r) == AST_PLUS, NULL );
  fail_unless( ASTNode_getCharacter  (r) == '+', NULL );
  fail_unless( ASTNode_getNumChildren(r) == 2  , NULL );

  c = ASTNode_getLeftChild(r);

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

  c = ASTNode_getRightChild(r);

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

  ASTNode_free(r);
}
/**
 * Formats the given ASTNode as an SBML L1 token and appends the result to
 * the given StringBuffer.
 */
void
FormulaFormatter_format (StringBuffer_t *sb, const ASTNode_t *node)
{
  if (sb == NULL) return;
  if (ASTNode_isOperator(node))
  {
    FormulaFormatter_formatOperator(sb, node);
  }
  else if (ASTNode_isFunction(node))
  {
    FormulaFormatter_formatFunction(sb, node);
  }
  else if (ASTNode_isInteger(node))
  {
    StringBuffer_appendInt(sb, ASTNode_getInteger(node));
  }
  else if (ASTNode_isRational(node))
  {
    FormulaFormatter_formatRational(sb, node);
  }
  else if (ASTNode_isReal(node))
  {
    FormulaFormatter_formatReal(sb, node);
  }
  else if ( !ASTNode_isUnknown(node) )
  {
    StringBuffer_append(sb, ASTNode_getName(node));
  }
}
/**
 * Formats the given ASTNode as an SBML L3 token and appends the result to
 * the given StringBuffer.
 */
void
L3FormulaFormatter_format (StringBuffer_t *sb, const ASTNode_t *node, const L3ParserSettings_t *settings)
{
  if (sb == NULL) return;
  if (L3FormulaFormatter_isFunction(node, settings))
  {
    L3FormulaFormatter_formatFunction(sb, node, settings);
  }
  else if (ASTNode_isOperator(node) || ASTNode_getType(node) == AST_FUNCTION_POWER)
  {
    L3FormulaFormatter_formatOperator(sb, node);
  }
  else if (ASTNode_isLogical(node) || ASTNode_isRelational(node))
  {
    L3FormulaFormatter_formatLogicalRelational(sb, node);
  }
  else if (ASTNode_isRational(node))
  {
    L3FormulaFormatter_formatRational(sb, node, settings);
  }
  else if (ASTNode_isInteger(node))
  {
    L3FormulaFormatter_formatReal(sb, node, settings);
  }
  else if (ASTNode_isReal(node))
  {
    L3FormulaFormatter_formatReal(sb, node, settings);
  }
  else if ( !ASTNode_isUnknown(node) )
  {
    StringBuffer_append(sb, ASTNode_getName(node));
  }
}
Esempio n. 9
0
/**
 * Formats the given ASTNode as a directed graph token and returns the result as
 * a string.
 */
char *
FormulaGraphvizFormatter_format (const ASTNode_t *node)
{
  StringBuffer_t *p = StringBuffer_create(128);
  char           *s = NULL;
 
  if (ASTNode_isOperator(node))
  {
    s = FormulaGraphvizFormatter_formatOperator(node);
  }
  else if (ASTNode_isFunction(node))
  {
    s = FormulaGraphvizFormatter_formatFunction(node);
  }
  else if (ASTNode_isInteger(node))
  {
    StringBuffer_appendInt(p, ASTNode_getInteger(node));
    s = StringBuffer_toString(p);
  }
  else if (ASTNode_isRational(node))
  {
    s = FormulaGraphvizFormatter_formatRational(node);
  }
  else if (ASTNode_isReal(node))
  {
    s = FormulaGraphvizFormatter_formatReal(node);
  }
  else if ( !ASTNode_isUnknown(node) )
  {
    if (ASTNode_getName(node) == NULL)
    {
      StringBuffer_append(p, "unknown");
    }
    else
    {
      StringBuffer_append(p, ASTNode_getName(node));
    }
    
    s = StringBuffer_toString(p);
  }
  
  free(p);

  return s;
}
Esempio n. 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);
    }
  }
}
END_TEST


START_TEST (test_SBML_parseFormula_13)
{
  ASTNode_t *r = SBML_parseFormula("foo()");


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

  ASTNode_free(r);
}
Esempio n. 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;
}
Esempio n. 13
0
END_TEST


START_TEST (test_FunctionDefinition_getBody)
{
  const ASTNode_t *math;

  ASTNode_t * math1 = SBML_parseFormula("lambda(x, x)");

  FunctionDefinition_setMath(FD, math1 );
  math = FunctionDefinition_getBody(FD);

  fail_unless( math != NULL                        );
  fail_unless( ASTNode_isName(math)                );
  fail_unless( !strcmp(ASTNode_getName(math), "x") );
  fail_unless( ASTNode_getNumChildren(math) == 0   );

  ASTNode_free(math1);
}
Esempio n. 14
0
/**
 * Formats the given ASTNode as an SBML L1 function name and appends the
 * result to the given StringBuffer.
 */
void
FormulaFormatter_formatFunction (StringBuffer_t *sb, const ASTNode_t *node)
{
  ASTNodeType_t type = ASTNode_getType(node);


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

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

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

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

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

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

    default:
      StringBuffer_append(sb, ASTNode_getName(node));
      break;
  }
}
Esempio n. 15
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;
}
Esempio n. 16
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"));
    }
}
Esempio n. 17
0
SBML_ODESOLVER_API double evaluateAST(ASTNode_t *n, cvodeData_t *data)
{
  int i, j, childnum;
  int found, datafound;
  int true;
  time_series_t *ts=data->model->time_series;
  double findtol=1e-5;
 
  ASTNodeType_t type;
  /* ASTNode_t **child; */

  /* value* are for intermediate values. */
  double value1, value2, value3, result;

  if ( n == NULL )
  {
    SolverError_error(FATAL_ERROR_TYPE,
		      SOLVER_ERROR_AST_UNKNOWN_NODE_TYPE,
		      "evaluateAST: empty Abstract Syntax Tree (AST).");
    return (0);
  }
  if ( ASTNode_isUnknown(n) )
  {
    SolverError_error(FATAL_ERROR_TYPE,
		      SOLVER_ERROR_AST_UNKNOWN_NODE_TYPE,
		      "evaluateAST: unknown ASTNode type");
  }
  result = 0;

  childnum = ASTNode_getNumChildren(n);
  type = ASTNode_getType(n);
  switch(type)
  {
  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:
    /** VARIABLES:

    find the value of the variable in the data->value
    array. SOSlib's extension to libSBML's AST allows to add the
    index of the variable in this array to AST_NAME
    (ASTIndexName). If the ASTNode is not indexed, its array
    index is searched via the data->model->names array, which
    corresponds to the data->value array. For nodes with name
    `Time' or `time' the data->currenttime is returned.  If no
    value is found a fatal error is produced. */
    found = 0;
    if ( ASTNode_isSetIndex(n) )
    {
      if ( ASTNode_isSetData(n) )
      {

        /* if continuous data is observed, obtain interpolated result */  
        if ( (data->model->discrete_observation_data != 1) || (data->model->compute_vector_v != 1) )
	{
	  result = call(ASTNode_getIndex(n),
			data->currenttime, ts);

	}
	else  /* if discrete data is observed, simply obtain value from time_series */
	{
          datafound = 0;
          i = data->TimeSeriesIndex;
        
	    if ( fabs(data->currenttime - ts->time[i]) < findtol )
	    {    
	      result = ts->data[ASTNode_getIndex(n)][i];
              datafound++;
	    }
	
          if ( datafound != 1)
	  {	            
	    SolverError_error(FATAL_ERROR_TYPE,
			SOLVER_ERROR_AST_EVALUATION_FAILED_DISCRETE_DATA,
			"use of discrete time series data failed; none or several time points matching current time");
	    result = 0;
           /*  break;  */
	  }
          else found = 1;

	}
      }
      else
      {
	/* majority case: just return the
	   according value from data->values
	   from the index stored by SOSlib
	   ASTIndexNameNode sub-class of libSBML's ASTNode */
	result = data->value[ASTNode_getIndex(n)];
  
      }
      
       found++;
    }

    if ( found == 0 )
    {
      for ( j=0; j<data->nvalues; j++ )
      {
	if ( (strcmp(ASTNode_getName(n),data->model->names[j]) == 0) )
	{
	  
	  result = data->value[j];
	  found++;
	}
      }
    }

    if ( found == 0 )
    {
      SolverError_error(FATAL_ERROR_TYPE,
			SOLVER_ERROR_AST_EVALUATION_FAILED_MISSING_VALUE,
			"No value found for AST_NAME %s . Defaults to Zero "
			"to avoid program crash", ASTNode_getName(n));
      result = 0;
    }
    break;

  case AST_FUNCTION_DELAY:
    SolverError_error(FATAL_ERROR_TYPE,
		      SOLVER_ERROR_AST_EVALUATION_FAILED_DELAY,
		      "Solving ODEs with Delay is not implemented. "
		      "Defaults to 0 to avoid program crash");
    result = 0.0;
    break;
  case AST_NAME_TIME:
    result = (double) data->currenttime;
    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 = 0.0;
    for ( i=0; i<childnum; i++) 
      result += evaluateAST(child(n,i),data);   
    break;      
  case AST_MINUS:
    if ( childnum<2 )
      result = - (evaluateAST(child(n,0),data));
    else
      result = evaluateAST(child(n,0),data) - evaluateAST(child(n,1),data);
    break;
  case AST_TIMES:
    result = 1.0;
    for ( i=0; i<childnum; i++)
    {
      result *= evaluateAST(child(n,i),data);
      if (result == 0.0) break; /* small optimization by skipping the rest of children */
    }
    break;
  case AST_DIVIDE:
    result = evaluateAST(child(n,0),data) / evaluateAST(child(n,1),data);
    break;
  case AST_POWER:
    result = pow(evaluateAST(child(n,0),data),evaluateAST(child(n,1),data));
    break;
  case AST_LAMBDA:
    SolverError_error(FATAL_ERROR_TYPE,
		      SOLVER_ERROR_AST_EVALUATION_FAILED_LAMBDA,
		      "Lambda can only be used in SBML function definitions."
		      " Defaults to 0 to avoid program crash");
    result = 0.0;
    break;
    /** FUNCTIONS: */
  case AST_FUNCTION:
    /**  Evaluate external functions, if it was set with
	 setUserDefinedFunction */      
    if ( UsrDefFunc == NULL )
    {
      SolverError_error(FATAL_ERROR_TYPE,
			SOLVER_ERROR_AST_EVALUATION_FAILED_FUNCTION,
			"The function %s() has not been defined "
			"in the SBML input model or as an externally "
			"supplied function. Defaults to 0 to avoid "
			"program crash",
			ASTNode_getName(n));
      result = 0.0;
    }
    else
    {
      double *func_vals = NULL;
      ASSIGN_NEW_MEMORY_BLOCK(func_vals, childnum+1, double, 0);
      for ( i=0; i<childnum; i++ ) 
	func_vals[i] = evaluateAST(child(n,i), data);      
      result = UsrDefFunc((char *)ASTNode_getName(n), childnum, func_vals);
      free(func_vals);
    }
    break;
  case AST_FUNCTION_ABS:
    result = fabs(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_ARCCOS:
    result = acos(evaluateAST(child(n,0),data)) ;
    break;
  case AST_FUNCTION_ARCCOSH:
    result = aCosh(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_ARCCOT:
    /** arccot x =  arctan (1 / x) */
    result = atan(1./ evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_ARCCOTH:
    /** arccoth x = 1/2 * ln((x+1)/(x-1)) */
    value1 = evaluateAST(child(n,0),data);
    result = log((value1 + 1) / (value1 - 1))/2;
    break;
  case AST_FUNCTION_ARCCSC:
    /** arccsc(x) = Arctan(1 / sqrt((x - 1)(x + 1))) */
    value1 = evaluateAST(child(n,0),data);
    result = atan(1/sqrt((value1-1)*(value1+1)));
    break;
  case AST_FUNCTION_ARCCSCH:
    /** arccsch(x) = ln((1/x) + sqrt((1/(x*x)) + 1)) */
    value1 = evaluateAST(child(n,0),data);
    result = log(1/value1 + sqrt(1/(value1*value1)+1));
    break;
  case AST_FUNCTION_ARCSEC:
    /** arcsec(x) = arccos(1/x) */
    result = acos(1/evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_ARCSECH:
    /* arcsech(x) = arccosh(1/x) */
    result = aCosh( 1. /  evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_ARCSIN:
    result = asin(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_ARCSINH:
    result = aSinh(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_ARCTAN:
    result = atan(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_ARCTANH:
    result = aTanh(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_CEILING:
    result = ceil(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_COS:
    result = cos(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_COSH:
    result = cosh(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_COT:
    /** cot x = 1 / tan x */
    result = (1./tan(evaluateAST(child(n,0),data)));
    break;
  case AST_FUNCTION_COTH:
    /** coth x = cosh x / sinh x */
    result = 1/tanh(evaluateAST(child(n,0),data));
    break;  
  case AST_FUNCTION_CSC:
    /** csc x = 1 / sin x */
    result = (1./sin(evaluateAST(child(n,0),data)));
    break;
  case AST_FUNCTION_CSCH:
    /** csch x = 1 / sinh x  */
    result = (1./sinh(evaluateAST(child(n,0),data)));
    break;
  case AST_FUNCTION_EXP:
    result = exp(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_FACTORIAL:
    {
      int j;
      value1 = evaluateAST(child(n,0),data);
      j = floor(value1);
      if ( value1 != j )
	SolverError_error(FATAL_ERROR_TYPE,
			  SOLVER_ERROR_AST_EVALUATION_FAILED_FLOAT_FACTORIAL,
			  "The factorial is only implemented."
			  "for integer values. The floor value of the "
			  "passed float is used for calculation!");

      for(result=1;j>1;--j)
	result *= j;
    }
    break;
  case AST_FUNCTION_FLOOR:
    result = floor(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_LN:
    result = log(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_LOG:
    /** log(x,y) = log10(y)/log10(x) (where x is the base)  */
    result = log10(evaluateAST(child(n,1),data)) /
      log10(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_PIECEWISE:
    /** Piecewise: */
    found = 0;
    /** Go through n pieces with 2 AST children for each piece, */
    for ( i=0; i<(childnum-1); i=i+2 )
    {
      if ( evaluateAST(child(n, i+1), data) )
      {
	found++;
	result = evaluateAST(child(n, i), data);
      }
    }
    /** odd number of AST children: if no piece was true, otherwise remains */
    /* i should be equal to childnum for even number piecewise AST
       and equal to childnum-1 for odd numbered piecewise ASTs */
    if ( i == childnum-1 && found == 0 )
    {
      found++;
      result = evaluateAST(child(n, i), data);
    }
    if ( found == 0 )
      SolverError_error(FATAL_ERROR_TYPE,
			SOLVER_ERROR_AST_EVALUATION_FAILED_PIECEWISE,
			"Piecewise function failed; no true piece");
    if ( found > 1 )
      SolverError_error(FATAL_ERROR_TYPE,
			SOLVER_ERROR_AST_EVALUATION_FAILED_PIECEWISE,
			"Piecewise function failed; several true pieces");
    break;
  case AST_FUNCTION_POWER:
    result = pow(evaluateAST(child(n,0),data),evaluateAST(child(n,1),data));
    break;
  case AST_FUNCTION_ROOT:
    /*!!! ALSO do this in compiled code */
    value1 = evaluateAST(child(n,1),data);
    value2 = evaluateAST(child(n,0),data);
    value3 = floor(value2);
    /* for odd root degrees, negative numbers are OK */
    if ( value2 == value3 ) /* check whether degree is integer */
    {
      if ( (value1 < 0) && ((int)value2 % 2 != 0) )
	result = - pow(fabs(value1), 1./value2);
      else
	result = pow(value1, 1./value2);	
    }
    else
      result = pow(value1, 1./value2);
    break;
  case AST_FUNCTION_SEC:
    /** sec x = 1 / cos x */
    result = 1./cos(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_SECH:
    /** sech x = 1 / cosh x */
    result = 1./cosh(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_SIN:
    result = sin(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_SINH:
    result = sinh(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_TAN:
    result = tan(evaluateAST(child(n,0),data));
    break;
  case AST_FUNCTION_TANH:
    result = tanh(evaluateAST(child(n,0),data));
    break;

  case AST_LOGICAL_AND:
    /** AND: all children must be true */
    true = 0;
    for ( i=0; i<childnum; i++ ) true += evaluateAST(child(n,i),data);
    if ( true == childnum ) result = 1.0;
    else result = 0.0;
    break;
  case AST_LOGICAL_NOT:
    result = (double) (!(evaluateAST(child(n,0),data)));
    break;
  case AST_LOGICAL_OR:
    /** OR: at least one child must be true */
    true = 0;
    for ( i=0; i<childnum; i++ ) true += evaluateAST(child(n,i),data);    
    if ( true > 0 ) result = 1.0;
    else result = 0.0;
    break;
  case AST_LOGICAL_XOR:
    /* n-ary: true if an odd number of children is true */
    true = 0;
    for ( i=0; i<childnum; i++ ) true += evaluateAST(child(n,i),data);    
    if ( true % 2 != 0 ) result = 1.0;
    else result = 0.0;
    break;
    /* !!! check n-ary definitions for relational operators !!! */
  case AST_RELATIONAL_EQ:
    /** n-ary: all children must be equal */
    result = 1.0;
    if (childnum <= 1) break;
    value1 = evaluateAST(child(n,0),data);
    for ( i=1; i<childnum; i++ )
      if ( value1 != evaluateAST(child(n,i),data) )
      {
        result = 0.0;
        break;
      }
    break;
  case AST_RELATIONAL_GEQ:
    /** n-ary: each child must be greater than or equal to the following */
    result = 1.0;
    if (childnum <= 1) break;
    value2 = evaluateAST(child(n,0),data);
    for ( i=1; i<childnum; i++ )
    {
      value1 = value2;
      value2 = evaluateAST(child(n,i),data);
      if (value1 < value2)
      {
        result = 0.0;
        break;
      }
    }
    break;
  case AST_RELATIONAL_GT:
    /** n-ary: each child must be greater than the following */
    result = 1.0;
    if (childnum <= 1) break;
    value2 = evaluateAST(child(n,0),data);
    for ( i=1; i<childnum; i++ )
    {
      value1 = value2;
      value2 = evaluateAST(child(n,i),data);
      if (value1 <= value2)
      {
        result = 0.0;
        break;
      }
    }
    break;
  case AST_RELATIONAL_LEQ:
    /** n-ary: each child must be lower than or equal to the following */
    result = 1.0;
    if (childnum <= 1) break;
    value2 = evaluateAST(child(n,0),data);
    for ( i=1; i<childnum; i++ )
    {
      value1 = value2;
      value2 = evaluateAST(child(n,i),data);
      if (value1 > value2)
      {
        result = 0.0;
        break;
      }
    }
    break;
  case AST_RELATIONAL_LT :
    /* n-ary: each child must be lower than the following */
    result = 1.0;
    if (childnum <= 1) break;
    value2 = evaluateAST(child(n,0),data);
    for ( i=1; i<childnum; i++ )
    {
      value1 = value2;
      value2 = evaluateAST(child(n,i),data);
      if (value1 >= value2)
      {
        result = 0.0;
        break;
      }
    }
    break;
  case AST_RELATIONAL_NEQ:
    /* binary "not equal" */
    result = (evaluateAST(child(n, 0), data) != evaluateAST(child(n, 1), data));
    break;
  default:
    SolverError_error(FATAL_ERROR_TYPE,
                      SOLVER_ERROR_AST_UNKNOWN_NODE_TYPE,
                      "evaluateAST: unknown ASTNode type: %d", type);
    result = 0;
    break;
  }
  
  return result;
}
void _prepare_reversible_fast_reaction(Model_t *m, myASTNode *myNode, myReaction *re, mySpecies *sp[], myParameter *param[], myCompartment *comp[], myReaction *re_whole[], double sim_time, double dt, double *time, myInitialAssignment *initAssign[], char *time_variant_target_id[], unsigned int num_of_time_variant_targets, timeVariantAssignments *timeVarAssign, char *target_id, int p_or_r, allocated_memory *mem){
  ASTNode_t *minus_node, *zero_node, *final_eq_node;
  myASTNode *eq_root_node;
  int minus_sign;

  if(myNode->left != NULL){
    _prepare_reversible_fast_reaction(m, myNode->left, re, sp, param, comp, re_whole, sim_time, dt, time, initAssign, time_variant_target_id, num_of_time_variant_targets, timeVarAssign, target_id, p_or_r, mem);
  }
  if(myNode->right != NULL){
    _prepare_reversible_fast_reaction(m, myNode->right, re, sp, param, comp, re_whole, sim_time, dt, time, initAssign, time_variant_target_id, num_of_time_variant_targets, timeVarAssign, target_id, p_or_r, mem);
  }
  if(ASTNode_getType(myNode->origin) == AST_NAME){
    if(strcmp(ASTNode_getName(myNode->origin), target_id) == 0){
      ASTNode_setType(myNode->origin, AST_INTEGER);
      ASTNode_setInteger(myNode->origin, 1);
      eq_root_node = myNode;
      minus_sign = 1;
      while(eq_root_node->parent != NULL){
        if(ASTNode_getType(eq_root_node->parent->origin) != AST_TIMES
            && ASTNode_getType(eq_root_node->parent->origin) != AST_DIVIDE){
          if(ASTNode_getType(eq_root_node->parent->origin) == AST_MINUS
              && eq_root_node->parent->right == eq_root_node){
            minus_sign *= -1;
          }
          if(eq_root_node->parent->parent != NULL){
            if(eq_root_node->parent->parent->left == eq_root_node->parent){
              eq_root_node->parent->parent->left = eq_root_node;
            }else{
              eq_root_node->parent->parent->right = eq_root_node;
            }
            eq_root_node->parent = eq_root_node->parent->parent;
          }else{
            eq_root_node->parent = NULL;
            break;
          } 
        }else{
          eq_root_node = eq_root_node->parent;
        }
      }
      final_eq_node = eq_root_node->origin;
      TRACE(("myASTNode is\n"));
      check_myAST(eq_root_node);
      ASTNode_recreate(eq_root_node, final_eq_node);
      if(minus_sign == -1){
        minus_node = ASTNode_createWithType(AST_MINUS);
        zero_node = ASTNode_createWithType(AST_INTEGER);
        ASTNode_setInteger(zero_node, 0);
        ASTNode_addChild(minus_node, zero_node);
        ASTNode_addChild(minus_node, final_eq_node);
        final_eq_node = minus_node;
      }
      if(p_or_r == 0){/* products coefficient */
        TRACE(("AST of product numerator is\n"));
        check_AST(final_eq_node, NULL);
        re->products_equili_numerator->math_length = get_equation(m, re->products_equili_numerator, sp, param, comp, re_whole, final_eq_node, 0, sim_time, dt, time, initAssign, time_variant_target_id, num_of_time_variant_targets, timeVarAssign, mem);
      }else{/* reactants coefficient */
        minus_node = ASTNode_createWithType(AST_MINUS);
        zero_node = ASTNode_createWithType(AST_INTEGER);
        ASTNode_setInteger(zero_node, 0);
        ASTNode_addChild(minus_node, zero_node);
        ASTNode_addChild(minus_node, final_eq_node);
        final_eq_node = minus_node;
        TRACE(("AST of reactant numerator is\n"));
        check_AST(final_eq_node, NULL);
        re->reactants_equili_numerator->math_length = get_equation(m, re->reactants_equili_numerator, sp, param, comp, re_whole, final_eq_node, 0, sim_time, dt, time, initAssign, time_variant_target_id, num_of_time_variant_targets, timeVarAssign, mem);
      }
    }
  }
}
Esempio n. 19
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;
}
Esempio n. 20
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;
}