예제 #1
0
int Submodel::convertTimeAndExtent()
{
  int ret=LIBSBML_OPERATION_SUCCESS;
  string tcf = "";
  ASTNode* tcf_ast = NULL;
  if (isSetTimeConversionFactor()) {
    tcf = getTimeConversionFactor();
    tcf_ast = new ASTNode(AST_NAME);
    tcf_ast->setName(tcf.c_str());
  }
  string xcf = "";
  ASTNode* xcf_ast = NULL;
  if (isSetExtentConversionFactor()) {
    xcf = getExtentConversionFactor();
    xcf_ast = new ASTNode(AST_NAME);
    xcf_ast->setName(xcf.c_str());
  }

  ASTNode* klmod = NULL;
  if (xcf_ast != NULL) {
    klmod = xcf_ast;
  }
  if (tcf_ast != NULL) {
    if (klmod==NULL) {
      klmod = new ASTNode(AST_INTEGER);
      klmod->setValue(1);
    }
    ASTNode* divide = new ASTNode(AST_DIVIDE);
    divide->addChild(klmod);
    divide->addChild(tcf_ast);
    klmod = divide;
  }

  ret = convertTimeAndExtentWith(tcf_ast, xcf_ast, klmod);
  delete klmod;
  return ret;
}
예제 #2
0
파일: Parser.cpp 프로젝트: meshula/Landru
void parseElse(CurrPtr& curr, EndPtr end) {
	getToken(curr, end);	// consume else

	if (!getColon(curr, end))
		return;

	ASTNode* pop = currNode;
	currNode = new ASTNode(kTokenElse);
	pop->addChild(currNode);

	parseStatements(curr, end, currNode);
	getSemiColon(curr, end);

	currNode = pop;
}
예제 #3
0
파일: Parser.cpp 프로젝트: meshula/Landru
void parseStatements(CurrPtr& curr, EndPtr end, ASTNode *& currNode)
{
	ASTNode* pop = currNode;
	ASTNode* ast = new ASTNode(kTokenStatements);
	pop->addChild(ast);
	currNode = ast;

	while (more(curr, end))
	{
		if (*curr == kTerminalChar) // ; at the end of the block of statements
		{
			break;
		}

		parseStatement(curr, end);
	}
	currNode = pop;
}
예제 #4
0
파일: Parser.cpp 프로젝트: meshula/Landru
void parseLandruVarDeclaration(CurrPtr& curr, EndPtr end, ASTNode *& currNode)
{
	bool sharedToken = peekToken(curr, end) == kTokenShared;
	bool paramToken = !sharedToken && peekToken(curr, end) == kTokenParam;
	if (sharedToken || paramToken)
		getToken(curr, end);

	char varType[256];
	getType(curr, end, varType);

    if (!strlen(varType))
        lcRaiseError("Expected variable type, found:", curr, 32);

	TokenId declaredType = peekToken(varType, varType+sizeof(varType));

	char name[256];
	getDeclarator(curr, end, name);

    if (!strlen(name))
        lcRaiseError("Expected variable name, found:", curr, 32);

	auto token = kTokenLocalVariable;
	if (sharedToken)
		token = kTokenSharedVariable;
	else if (paramToken)
		token = kTokenParam;

	ASTNode * variableNode = new ASTNode(token, varType, name);
	currNode->addChild(variableNode);

	token = peekToken(curr, end);
	if (token == kTokenEq) {
		getToken(curr, end); // consume assignment operator
		ASTNode * pop = currNode;
		if (sharedToken)
			currNode = new ASTNode(kTokenInitialAssignment, name);
		else
			currNode = new ASTNode(kTokenAssignment, name);
		variableNode->addChild(currNode);
		parseLiteral(curr, end, currNode, declaredType); // and put the assigned value in the tree
		currNode = pop;
	}
}
END_TEST


START_TEST (test_MathMLFromAST_function_2)
{
  const char* expected = wrapMathML
  (
    "  <apply>\n"
    "    <ci> foo </ci>\n"
    "    <cn type=\"integer\"> 1 </cn>\n"
    "    <cn type=\"integer\"> 2 </cn>\n"
    "    <apply>\n"
    "      <ci> bar </ci>\n"
    "      <ci> z </ci>\n"
    "    </apply>\n"
    "  </apply>\n"
  );

  // N = SBML_parseFormula("foo(1, 2, bar(z))");
  N = new ASTNode(AST_FUNCTION);
  fail_unless( N->setName("foo") == LIBSBML_OPERATION_SUCCESS);
  
  ASTNode *c1 = new ASTNode(AST_INTEGER);
  c1->setValue(long(1));
  ASTNode *c2 = new ASTNode(AST_INTEGER);
  c2->setValue(long(2));

  ASTNode *bar = new ASTNode(AST_FUNCTION);
  bar->setName("bar");

  ASTNode *cz = new ASTNode(AST_NAME);
  cz->setName("z");

  fail_unless (bar->addChild(cz) == LIBSBML_OPERATION_SUCCESS);

  fail_unless (N->addChild(c1) == LIBSBML_OPERATION_SUCCESS);
  fail_unless (N->addChild(c2) == LIBSBML_OPERATION_SUCCESS);
  fail_unless (N->addChild(bar) == LIBSBML_OPERATION_SUCCESS);

  S = writeMathMLToString(N);

  fail_unless( equals(expected, S) );
}
예제 #6
0
파일: Parser.cpp 프로젝트: meshula/Landru
void parseFunction(CurrPtr& curr, EndPtr end, TokenId token) {
	char buff[256];
	getNameSpacedDeclarator(curr, end, buff);   // get function name

	ASTNode* pop = currNode;
	currNode = new ASTNode(token, buff);
	pop->addChild(currNode);

    parseParamList(curr, end);
    currNode = pop;

    more(curr, end);
    if (peekChar(curr, end) == '.') {
        // chained functions assume that the previous function left something on the stack
        // which can have a function invoked on it.
        ++curr;
        currNode->addChild(new ASTNode(kTokenDotChain, buff));
        parseFunction(curr, end, kTokenFunction);
    }
}
예제 #7
0
파일: Parser.cpp 프로젝트: meshula/Landru
void parseOn(CurrPtr& curr, EndPtr end) {
	getToken(curr, end); // consume on

	char name[256];
	name[0] = '\0';
	TokenId what = peekToken(curr, end);
	if (what == kTokenUnknown) {
		char const* tokenStr;
		uint32_t length;
		curr = tsGetNameSpacedTokenAlphaNumeric(curr, end, '.', &tokenStr, &length);
		strncpy(name, tokenStr, length);
		name[length] = '\0';
		what = kTokenFunction;
	}
	else {
		getToken(curr, end);
	}

    ASTNode* pop = currNode;
	ASTNode* onNode = new ASTNode(kTokenOn);
	currNode->addChild(onNode);
	currNode = onNode;
	ASTNode* eventNode = new ASTNode(what, name);
	onNode->addChild(eventNode);
	currNode = eventNode;				// curr is now the qualifier, eg. message

    more(curr, end);
    if (peekChar(curr, end) == '(')
        parseParamList(curr, end);

	currNode = onNode;

	if (!getColon(curr, end))
		return;

	parseStatements(curr, end, currNode);
	getSemiColon(curr, end);

	currNode = pop;
}
예제 #8
0
ASTNode* CEvaluationNodeCall::toAST(const CCopasiDataModel* pDataModel) const
{
  ASTNode* pNode = NULL;

  pNode = new ASTNode(AST_FUNCTION);
  const std::string funName = this->getData();
  CFunction * pFun = CCopasiRootContainer::getFunctionList()->findFunction(funName);
  assert(pFun != NULL);

  if (pFun == NULL || pFun->getSBMLId().empty()) fatalError();

  pNode->setName(pFun->getSBMLId().c_str());

  const CEvaluationNode* child = static_cast<const CEvaluationNode*>(this->getChild());

  while (child)
    {
      pNode->addChild(child->toAST(pDataModel));
      child = static_cast<const CEvaluationNode*>(child->getSibling());
    }

  return pNode;
}
END_TEST


START_TEST (test_MathMLFromAST_plus_nary_3)
{
  const char* expected = wrapMathML
  (
    "  <apply>\n"
    "    <plus/>\n"
    "    <cn type=\"integer\"> 1 </cn>\n"
    "    <cn type=\"integer\"> 2 </cn>\n"
    "    <cn type=\"integer\"> 3 </cn>\n"
    "  </apply>\n"
  );

//  N = SBML_parseFormula("1 + (2 + 3)");
  
  N = new ASTNode(AST_PLUS);
  
  ASTNode *c1 = new ASTNode(AST_INTEGER);
  c1->setValue(1);
  ASTNode *c2 = new ASTNode(AST_INTEGER);
  c2->setValue(2);
  ASTNode *c3 = new ASTNode(AST_INTEGER);
  c3->setValue(3);
  
  ASTNode *plus = new ASTNode(AST_PLUS);
  plus->addChild(c2);
  plus->addChild(c3);
  
  N->addChild(c1);
  N->addChild(plus);
  
  S = writeMathMLToString(N);

  fail_unless( equals(expected, S) );
}
END_TEST


START_TEST (test_MathMLFromAST_replaceIDWithFunction_1)
{
  const char* expected = wrapMathML
  (
    "  <apply>\n"
    "    <plus/>\n"
    "    <cn> 1 </cn>\n"
    "  </apply>\n"
  );

  const char* original = wrapMathML
  (
    "  <ci> x </ci>\n"
  );

  N = new ASTNode(AST_NAME);
  N->setName("x");

  ASTNode *replaced = new ASTNode(AST_PLUS);
  ASTNode *c = new ASTNode();
  c->setValue(1.0);
  replaced->addChild(c);
  
  S = writeMathMLToString(N);

  fail_unless( equals(original, S) );

  N->replaceIDWithFunction("x", replaced);

  S = writeMathMLToString(N);

  fail_unless( equals(expected, S) );

}
END_TEST

START_TEST (test_UnitFormulaFormatter_getUnitDefinition_piecewise)
{
  UnitDefinition * ud = new UnitDefinition(2, 4);

  ud = uff->getUnitDefinition(m->getRule(7)->getMath());

  fail_unless(ud->getNumUnits() == 1);

  fail_unless(!strcmp(ud->getId().c_str(), ""), NULL);

  fail_unless(ud->getUnit(0)->getMultiplier() == 1);
  fail_unless(ud->getUnit(0)->getScale() == 0);
  fail_unless(ud->getUnit(0)->getExponent() == 1);
  fail_unless(ud->getUnit(0)->getOffset() == 0.0);
  fail_unless(ud->getUnit(0)->getKind() == UNIT_KIND_METRE);

  /* check deals with invalid nodes */
  delete ud;
  UnitDefinition * ud1 = new UnitDefinition(m->getLevel(), m->getVersion());
  ASTNode *node = new ASTNode(AST_FUNCTION_PIECEWISE);

  ud1 == uff->getUnitDefinition(node);

  fail_unless (ud1->getNumUnits() == 0);

  ASTNode *c = new ASTNode(AST_UNKNOWN);
  node->addChild(c);
  
  ud1 == uff->getUnitDefinition(node);

  fail_unless (ud1->getNumUnits() == 0);

  delete ud1;
  delete node;
}
예제 #12
0
LIBSBML_CPP_NAMESPACE_USE

int
main (int argc, char* argv[])
{
  SBMLNamespaces sbmlns(3,1,"arrays",1);

  // create the document

  SBMLDocument *document = new SBMLDocument(&sbmlns);

  // set the required attribute to true
  ArraysSBMLDocumentPlugin * docPlug = 
    static_cast<ArraysSBMLDocumentPlugin*>(document->getPlugin("arrays"));
  docPlug->setRequired(true);


  // create the Model

  Model* model=document->createModel();

  // create the parameters

  // first parameter - for dimension m
  Parameter * p = model->createParameter();
  p->setId("m");
  p->setConstant(true);
  p->setValue(2);

  // second parameter - for dimension n
  p = model->createParameter();
  p->setId("n");
  p->setConstant(true);
  p->setValue(1);

  // third parameter - 2 x 1 matrix of parameters
  p = model->createParameter();
  p->setId("x");
  p->setConstant(false);


  // create the Dimensions via the Plugin
  ArraysSBasePlugin * arraysPlug = 
    static_cast<ArraysSBasePlugin*>(p->getPlugin("arrays"));

  // first dimension
  Dimension * dim = arraysPlug->createDimension();
  dim->setArrayDimension(0);
  dim->setSize("m");

  // second dimension
  dim = arraysPlug->createDimension();
  dim->setArrayDimension(1);
  dim->setSize("n");

  // other parameters
  p = model->createParameter();
  p->setId("y");
  p->setConstant(true);
  p->setValue(2.3);



  // create the initialAssignment
  InitialAssignment *ia = model->createInitialAssignment();
  ia->setSymbol("x");

  ASTNode * row1 = new ASTNode(AST_LINEAR_ALGEBRA_VECTOR_CONSTRUCTOR);
  
  ASTNode * ci1 = new ASTNode(AST_NAME);
  ci1->setName("y");
  
  row1->addChild(ci1);

  ASTNode * row2 = new ASTNode(AST_LINEAR_ALGEBRA_VECTOR_CONSTRUCTOR);
  
  ASTNode * ci2 = new ASTNode(AST_INTEGER);
  ci2->setValue(2);

  row2->addChild(ci2);

  ASTNode * math = new ASTNode(AST_LINEAR_ALGEBRA_VECTOR_CONSTRUCTOR);

  math->addChild(row1);
  math->addChild(row2);

  ia->setMath(math);

  writeSBML(document,"arrays_example3.xml");
 
  delete document;

  return 0;
}
END_TEST


START_TEST (test_MathMLFromAST_matrix)
{
  const char* expected = wrapMathML
  (
    "  <matrix>\n"
    "    <matrixrow>\n"
    "      <apply>\n"
    "        <cos/>\n"
    "        <cn type=\"integer\"> 5 </cn>\n"
    "      </apply>\n"
    "      <ci> y </ci>\n"
    "    </matrixrow>\n"
    "    <matrixrow>\n"
    "      <cn type=\"integer\"> 2 </cn>\n"
    "      <cn type=\"integer\"> 4 </cn>\n"
    "    </matrixrow>\n"
    "  </matrix>\n"
  );


  ASTNode * y = new ASTNode(AST_NAME);
  fail_unless(y->setName("y") == LIBSBML_OPERATION_SUCCESS);

  ASTNode *int1 = new ASTNode(AST_INTEGER);
  fail_unless(int1->setValue((long)(5)) == LIBSBML_OPERATION_SUCCESS);

  ASTNode *cos = new ASTNode(AST_FUNCTION_COS);
  fail_unless(cos->addChild(int1) == LIBSBML_OPERATION_SUCCESS);

  ASTNode *row1 = new ASTNode(AST_LINEAR_ALGEBRA_MATRIXROW_CONSTRUCTOR);
  fail_unless( row1->getPackageName() == "arrays");

  fail_unless(row1->addChild(cos) == LIBSBML_OPERATION_SUCCESS);
  fail_unless(row1->addChild(y) == LIBSBML_OPERATION_SUCCESS);


  ASTNode *int2 = new ASTNode(AST_INTEGER);
  fail_unless(int2->setValue((long)(2)) == LIBSBML_OPERATION_SUCCESS);

  ASTNode *int3 = new ASTNode(AST_INTEGER);
  fail_unless(int3->setValue((long)(4)) == LIBSBML_OPERATION_SUCCESS);

  ASTNode *row2 = new ASTNode(AST_LINEAR_ALGEBRA_MATRIXROW_CONSTRUCTOR);
  fail_unless( row2->getPackageName() == "arrays");

  fail_unless(row2->addChild(int2) == LIBSBML_OPERATION_SUCCESS);
  fail_unless(row2->addChild(int3) == LIBSBML_OPERATION_SUCCESS);

  N = new ASTNode(AST_LINEAR_ALGEBRA_MATRIX_CONSTRUCTOR);
  fail_unless( N->getPackageName() == "arrays");

  fail_unless(N->addChild(row1) == LIBSBML_OPERATION_SUCCESS);
  fail_unless(N->addChild(row2) == LIBSBML_OPERATION_SUCCESS);

  S = writeMathMLToString(N);

  fail_unless( equals(expected, S) );
}
예제 #14
0
파일: Parser.cpp 프로젝트: meshula/Landru
void parseParamList(CurrPtr& curr, EndPtr end) {
	// if parsing a function, then an opening paren must have been encountered
	if (peekChar(curr, end) != '(') {
		lcRaiseError("Expecting a parameter list, no opening parenthesis found", curr, 32);
		return;
	}

    std::vector<std::string> paramList;
    parseExpression(curr, end, paramList);

    // closing paren
    if (peekChar(curr, end) == ')')
        getChar(curr, end);  // consume ')'
	else
		lcRaiseError("Expected closing parenthesis, found", curr, 32);

    ASTNode* popNode = currNode;

    std::vector<ASTNode*> nodeStack; // this is where the things that get parameters go

    ASTNode* paramNode = 0;
    for (auto i = paramList.begin(); i != paramList.end(); ++i) {
        const std::string& s = *i;
        const char* strstart = s.c_str();
        const char* strend = strstart + s.size();

        if (s == "(") {
            nodeStack.push_back(currNode);
            currNode = new ASTNode(kTokenParameters);
        }
        else if (s == ")") {
            paramNode = currNode;
            currNode = nodeStack.back();
            nodeStack.pop_back();
        }
        else if (*(strend - 1) == '#') {
            if (!paramNode)
                lcRaiseError("Missing parameters for function", curr, 32);

            std::string funcName;
            funcName = s.substr(0, s.size() - 1);
            ASTNode* functionNode = new ASTNode(kTokenFunction, funcName.c_str());
            functionNode->addChild(paramNode);
            paramNode = 0;
            currNode->addChild(functionNode);
        }
        else if (peekIsLiteral(strstart, strend))
            parseLiteral(strstart, strend, currNode, kTokenNullLiteral);
        else if (s == "*")
            currNode->addChild(new ASTNode(kTokenOpMultiply));
        else if (s == "+")
            currNode->addChild(new ASTNode(kTokenOpAdd));
        else if (s == "/")
            currNode->addChild(new ASTNode(kTokenOpDivide));
        else if (s == "-")
            currNode->addChild(new ASTNode(kTokenOpSubtract));
        else if (s == "!")
            currNode->addChild(new ASTNode(kTokenOpNegate));
        else if (s == "%")
            currNode->addChild(new ASTNode(kTokenOpModulus));
        else if (s == ">")
            currNode->addChild(new ASTNode(kTokenOpGreaterThan));
        else if (s == "<")
            currNode->addChild(new ASTNode(kTokenOpLessThan));
        //else if (s == "=")
        //    pushAssign();
        else if (s[0] == '@')
			currNode->addChild(new ASTNode(kTokenGetVariableReference, strstart+1));
		else
            currNode->addChild(new ASTNode(kTokenGetVariable, strstart));
    }
    if (!nodeStack.empty() || !paramNode)
        lcRaiseError("Unmatched parenthesis in expression", curr, 32);

    currNode = popNode;
    currNode->addChild(paramNode);
}
예제 #15
0
int Submodel::convertTimeAndExtentWith(const ASTNode* tcf, const ASTNode* xcf, const ASTNode* klmod)
{
  if (tcf==NULL && xcf==NULL) return LIBSBML_OPERATION_SUCCESS;
  Model* model = getInstantiation();
  if (model==NULL) {
    //getInstantiation sets its own error messages.
    return LIBSBML_OPERATION_FAILED;
  }
  ASTNode* tcftimes = NULL;
  ASTNode* tcfdiv = NULL;
  if (tcf != NULL) {
    tcftimes = new ASTNode(AST_TIMES);
    tcftimes->addChild(tcf->deepCopy());
    tcfdiv = new ASTNode(AST_DIVIDE);
    tcfdiv->addChild(tcf->deepCopy());
  }
  ASTNode* rxndivide = NULL;
  if (klmod != NULL) {
    rxndivide = new ASTNode(AST_DIVIDE);
    ASTNode rxnref(AST_NAME);
    rxndivide->addChild(rxnref.deepCopy());
    rxndivide->addChild(klmod->deepCopy());
  }
  List* allelements = model->getAllElements();
  for (unsigned int el=0; el<allelements->getSize(); el++) {
    SBase* element = static_cast<SBase*>(allelements->get(el));
    assert(element != NULL);
    ASTNode* ast1 = NULL;
    ASTNode* ast2 = NULL;
    Constraint* constraint = NULL;
    Delay* delay = NULL;
    EventAssignment* ea = NULL;
    InitialAssignment* ia = NULL;
    KineticLaw* kl = NULL;
    Priority* priority = NULL;
    RateRule* rrule = NULL;
    Rule* rule = NULL;
    Submodel* submodel = NULL;
    Trigger* trigger = NULL;
    string cf = "";
    //Reaction math will be converted below, in the bits with the kinetic law.  But because of that, we need to handle references *to* the reaction:  even if it has no kinetic law, the units have changed, and this needs to be reflected by the flattening routine.
    if (rxndivide != NULL && element->getTypeCode()==SBML_REACTION && element->isSetId()) {
      rxndivide->getChild(0)->setName(element->getId().c_str());
      for (unsigned int sube=0; sube<allelements->getSize(); sube++) {
        SBase* subelement = static_cast<SBase*>(allelements->get(sube));
        subelement->replaceSIDWithFunction(element->getId(), rxndivide);
      }
    }

    //Submodels need their timeConversionFactor and extentConversionFactor attributes converted.  We're moving top-down, so all we need to do here is fix the conversion factor attributes themselves, pointing them to new parameters if need be.
    if ((tcf !=NULL || xcf != NULL) && element->getTypeCode()==SBML_COMP_SUBMODEL) {
      submodel = static_cast<Submodel*>(element);
      if (tcf != NULL) {
        if (submodel->isSetTimeConversionFactor()) {
          createNewConversionFactor(cf, tcf, submodel->getTimeConversionFactor(), model);
          submodel->setTimeConversionFactor(cf);
        }
        else {
          submodel->setTimeConversionFactor(tcf->getName());
        }
      }
      if (xcf != NULL) {
        if (submodel->isSetExtentConversionFactor()) {
          createNewConversionFactor(cf, xcf, submodel->getExtentConversionFactor(), model);
          submodel->setExtentConversionFactor(cf);
        }
        else {
          submodel->setExtentConversionFactor(xcf->getName());
        }
      }
    }
    if (tcf==NULL) {
      if (klmod !=NULL && element->getTypeCode()==SBML_KINETIC_LAW) {
        kl = static_cast<KineticLaw*>(element);
        if (kl->isSetMath()) {
          ast1 = new ASTNode(AST_TIMES);
          ast1->addChild(klmod->deepCopy());
          ast1->addChild(kl->getMath()->deepCopy());
          kl->setMath(ast1);
          delete ast1;
        }
      }
    }
    else {
      // All math 'time' and 'delay' csymbols must still be converted.
      // Also, several constructs are modified directly.
      switch(element->getTypeCode()) {
        //This would be a WHOLE LOT SIMPLER if there was a 'hasMath' class in libsbml.  But even so, it would have to
        // handle the kinetic laws, rate rules, and delays separately.
      case SBML_KINETIC_LAW:
        //Kinetic laws are multiplied by 'klmod'.
        kl = static_cast<KineticLaw*>(element);
        ast1 = kl->getMath()->deepCopy();
        convertCSymbols(ast1, tcfdiv, tcftimes);
        if (klmod !=NULL) {
          kl = static_cast<KineticLaw*>(element);
          if (kl->isSetMath()) {
            ast2 = new ASTNode(AST_TIMES);
            ast2->addChild(klmod->deepCopy());
            ast2->addChild(ast1);
            kl->setMath(ast2);
            delete ast2;
          }
        }
        else {
          kl->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_DELAY:
        //Delays are multiplied by the time conversion factor.
        delay = static_cast<Delay*>(element);
        if (delay->isSetMath()) {
          ast1 = delay->getMath()->deepCopy();
          convertCSymbols(ast1, tcfdiv, tcftimes);
          tcftimes->addChild(ast1);
          delay->setMath(tcftimes);
          tcftimes->removeChild(1);
        }
        break;
      case SBML_RATE_RULE:
        //Rate rules are divided by the time conversion factor.
        rrule = static_cast<RateRule*>(element);
        if (rrule->isSetMath()) {
          ast1 = rrule->getMath()->deepCopy();
          tcfdiv->insertChild(0, rrule->getMath()->deepCopy());
          rrule->setMath(tcfdiv);
          tcfdiv->removeChild(0);
        }
        //Fall through to:
      case SBML_ASSIGNMENT_RULE:
      case SBML_ALGEBRAIC_RULE:
        //Rules in general need csymbols converted.
        rule = static_cast<Rule*>(element);
        if (rule->isSetMath()) {
          ast1 = rule->getMath()->deepCopy();
          convertCSymbols(ast1, tcfdiv, tcftimes);
          rule->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_EVENT_ASSIGNMENT:
        //Event assignments need csymbols converted.
        ea = static_cast<EventAssignment*>(element);
        if (ea->isSetMath()) {
          ast1 = ea->getMath()->deepCopy();
          convertCSymbols(ast1, tcfdiv, tcftimes);
          ea->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_INITIAL_ASSIGNMENT:
        //Initial assignments need csymbols converted.
        ia = static_cast<InitialAssignment*>(element);
        if (ia->isSetMath()) {
          ast1 = ia->getMath()->deepCopy();
          convertCSymbols(ast1, tcfdiv, tcftimes);
          ia->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_CONSTRAINT:
        //Constraints need csymbols converted.
        constraint = static_cast<Constraint*>(element);
        if (constraint->isSetMath()) {
          ast1 = constraint->getMath()->deepCopy();
          convertCSymbols(ast1, tcfdiv, tcftimes);
          constraint->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_PRIORITY:
        //Priorities need csymbols converted.
        priority = static_cast<Priority*>(element);
        if (priority->isSetMath()) {
          ast1 = priority->getMath()->deepCopy();
          convertCSymbols(ast1, tcfdiv, tcftimes);
          priority->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_TRIGGER:
        //Triggers need csymbols converted.
        trigger = static_cast<Trigger*>(element);
        if (trigger->isSetMath()) {
          ast1 = trigger->getMath()->deepCopy();
          convertCSymbols(ast1, tcfdiv, tcftimes);
          trigger->setMath(ast1);
          delete ast1;
        }
        break;
      default:
        //Do nothing!  If we wanted to call a plugin routine, this would be the place.  The only other alternative is to #ifdef some code in here that deals with the math-containing package objects explicitly.  Which might be the best option, all told.
        break;
      }
    }
  }

  delete allelements;

  return LIBSBML_OPERATION_SUCCESS;
}
/**
 *
 * Creates an SBML model represented in "7.1 A Simple example application of SBML"
 * in the SBML Level 2 Version 4 Specification.
 *
 */
SBMLDocument* createExampleEnzymaticReaction()
{
  const unsigned int level   = Level;
  const unsigned int version = Version;

  //---------------------------------------------------------------------------
  //
  // Creates an SBMLDocument object 
  //
  //---------------------------------------------------------------------------

  SBMLDocument* sbmlDoc = new SBMLDocument(level,version);

  //---------------------------------------------------------------------------
  //
  // Creates a Model object inside the SBMLDocument object. 
  //
  //---------------------------------------------------------------------------

  Model* model = sbmlDoc->createModel();
  model->setId("EnzymaticReaction");

  //---------------------------------------------------------------------------
  //
  // Creates UnitDefinition objects inside the Model object.
  //
  //---------------------------------------------------------------------------

  // Temporary pointers (reused more than once below).

  UnitDefinition* unitdef;
  Unit* unit;

  //---------------------------------------------------------------------------  
  // (UnitDefinition1) Creates an UnitDefinition object ("per_second")
  //---------------------------------------------------------------------------

  unitdef = model->createUnitDefinition();
  unitdef->setId("per_second");

  //  Creates an Unit inside the UnitDefinition object 

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_SECOND);
  unit->setExponent(-1);

  //--------------------------------------------------------------------------------
  // (UnitDefinition2) Creates an UnitDefinition object ("litre_per_mole_per_second") 
  //--------------------------------------------------------------------------------
    
  // Note that we can reuse the pointers 'unitdef' and 'unit' because the
  // actual UnitDefinition object (along with the Unit objects within it)
  // is already attached to the Model object.

  unitdef = model->createUnitDefinition();
  unitdef->setId("litre_per_mole_per_second");
    
  //  Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_MOLE);
  unit->setExponent(-1);

  //  Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_LITRE);
  unit->setExponent(1);

  //  Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_SECOND);
  unit->setExponent(-1);


  //---------------------------------------------------------------------------
  //
  // Creates a Compartment object inside the Model object. 
  //
  //---------------------------------------------------------------------------

  Compartment* comp;
  const string compName = "cytosol";

  // Creates a Compartment object ("cytosol")

  comp = model->createCompartment();
  comp->setId(compName);
 
  // Sets the "size" attribute of the Compartment object.
  //
  // We are not setting the units on the compartment size explicitly, so
  // the units of this Compartment object will be the default SBML units of
  // volume, which are liters.
  //
  comp->setSize(1e-14);


  //---------------------------------------------------------------------------
  //
  // Creates Species objects inside the Model object. 
  //
  //---------------------------------------------------------------------------
  
  // Temporary pointer (reused more than once below).
  
  Species *sp;

  //---------------------------------------------------------------------------
  // (Species1) Creates a Species object ("ES")
  //---------------------------------------------------------------------------

  // Create the Species objects inside the Model object. 

  sp = model->createSpecies();
  sp->setId("ES");
  sp->setName("ES");

  // Sets the "compartment" attribute of the Species object to identify the 
  // compartment in which the Species object is located.

  sp->setCompartment(compName);

  // Sets the "initialAmount" attribute of the Species object.
  //
  //  In SBML, the units of a Species object's initial quantity are
  //  determined by two attributes, "substanceUnits" and
  //  "hasOnlySubstanceUnits", and the "spatialDimensions" attribute
  //  of the Compartment object ("cytosol") in which the species
  //  object is located.  Here, we are using the default values for
  //  "substanceUnits" (which is "mole") and "hasOnlySubstanceUnits"
  //  (which is "false").  The compartment in which the species is
  //  located uses volume units of liters, so the units of these
  //  species (when the species appear in numerical formulas in the
  //  model) will be moles/liters.  
  //
  sp->setInitialAmount(0);

  //---------------------------------------------------------------------------
  // (Species2) Creates a Species object ("P")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setCompartment(compName);
  sp->setId("P");
  sp->setName("P");
  sp->setInitialAmount(0);

  //---------------------------------------------------------------------------
  // (Species3) Creates a Species object ("S")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setCompartment(compName);
  sp->setId("S");
  sp->setName("S");
  sp->setInitialAmount(1e-20);

  //---------------------------------------------------------------------------
  // (Species4) Creates a Species object ("E")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setCompartment(compName);
  sp->setId("E");
  sp->setName("E");
  sp->setInitialAmount(5e-21);

  
  //---------------------------------------------------------------------------
  //
  // Creates Reaction objects inside the Model object. 
  //
  //---------------------------------------------------------------------------
  
  // Temporary pointers.

  Reaction* reaction;
  SpeciesReference* spr;
  KineticLaw* kl;

  //---------------------------------------------------------------------------
  // (Reaction1) Creates a Reaction object ("veq").
  //---------------------------------------------------------------------------

  reaction = model->createReaction();
  reaction->setId("veq");

  // (Reactant1) Creates a Reactant object that references Species "E"
  // in the model.  The object will be created within the reaction in the
  // SBML <listOfReactants>.

  spr = reaction->createReactant();
  spr->setSpecies("E");

  // (Reactant2) Creates a Reactant object that references Species "S"
  // in the model.

  spr = reaction->createReactant();
  spr->setSpecies("S");

  //---------------------------------------------------------------------------
  // (Product1) Creates a Product object that references Species "ES" in
  // the model.
  //---------------------------------------------------------------------------

  spr = reaction->createProduct();
  spr->setSpecies("ES");

  //---------------------------------------------------------------------------
  // Creates a KineticLaw object inside the Reaction object ("veq"). 
  //---------------------------------------------------------------------------

  kl = reaction->createKineticLaw();

 //---------------------------------------------------------------------------
   // Creates an ASTNode object which represents the following math of the
   // KineticLaw.
   //
   //      <math xmlns="http://www.w3.org/1998/Math/MathML">
   //        <apply>
   //          <times/>
   //          <ci> cytosol </ci>
   //          <apply>
   //            <minus/>
   //            <apply>
   //              <times/>
   //              <ci> kon </ci>
   //              <ci> E </ci>
   //              <ci> S </ci>
   //            </apply>
   //            <apply>
   //              <times/>
   //              <ci> koff </ci>
   //              <ci> ES </ci>
   //            </apply>
   //          </apply>
   //        </apply>
   //      </math>
   //
 //---------------------------------------------------------------------------

   //------------------------------------------
   //
   // create nodes representing the variables
   //
   //------------------------------------------

   ASTNode* astCytosol = new ASTNode(AST_NAME);
   astCytosol->setName("cytosol");

   ASTNode* astKon = new ASTNode(AST_NAME);
   astKon->setName("kon");

   ASTNode* astKoff = new ASTNode(AST_NAME);
   astKoff->setName("koff");

   ASTNode* astE = new ASTNode(AST_NAME);
   astE->setName("E");

   ASTNode* astS = new ASTNode(AST_NAME);
   astS->setName("S");

   ASTNode* astES = new ASTNode(AST_NAME);
   astES->setName("ES");


   //--------------------------------------------
   //
   // create node representing
   //            <apply>
   //              <times/>
   //              <ci> koff </ci>
   //              <ci> ES </ci>
   //            </apply>
   //
   //--------------------------------------------

   ASTNode *astTimes1 = new ASTNode(AST_TIMES);
   astTimes1->addChild(astKoff);
   astTimes1->addChild(astES);

   //--------------------------------------------
   //
   // create node representing
   //            <apply>
   //              <times/>
   //              <ci> kon </ci>
   //              <ci> E </ci>
   //              <ci> S </ci>
   //            </apply>
   //
   //
   // (NOTES)
   //
   //  Since there is a restriction with an ASTNode of "<times/>" operation
   //  such that the ASTNode is a binary class and thus only two operands can
   //  be directly added, the following code in this comment block is invalid
   //  because the code directly adds three <ci> ASTNodes to <times/> ASTNode.
   //
   //    ASTNode *astTimes = new ASTNode(AST_TIMES);
   //    astTimes->addChild(astKon);
   //    astTimes->addChild(astE);
   //    astTimes->addChild(astS);
   //
   // The following valid code after this comment block creates the ASTNode
   // as a binary tree.
   //
   // Please see "Converting between ASTs and text strings" described
   // at http://sbml.org/Software/libSBML/docs/cpp-api/class_a_s_t_node.html
   // for the detailed information.
   //
   //--------------------------------------------

   ASTNode *astTimes2 = new ASTNode(AST_TIMES);
   astTimes2->addChild(astE);
   astTimes2->addChild(astS);

   ASTNode *astTimes = new ASTNode(AST_TIMES);
   astTimes->addChild(astKon);
   astTimes->addChild(astTimes2);

   //--------------------------------------------
   //
   // create node representing
   //          <apply>
   //            <minus/>
   //            <apply>
   //              <times/>
   //              <ci> kon </ci>
   //              <ci> E </ci>
   //              <ci> S </ci>
   //            </apply>
   //            <apply>
   //              <times/>
   //              <ci> koff </ci>
   //              <ci> ES </ci>
   //            </apply>
   //          </apply>
   //
   //--------------------------------------------

   ASTNode *astMinus = new ASTNode(AST_MINUS);
   astMinus->addChild(astTimes);
   astMinus->addChild(astTimes1);


   //--------------------------------------------
   //
   // create node representing
   //        <apply>
   //          <times/>
   //          <ci> cytosol </ci>
   //          <apply>
   //            <minus/>
   //            <apply>
   //              <times/>
   //              <ci> kon </ci>
   //              <ci> E </ci>
   //              <ci> S </ci>
   //            </apply>
   //            <apply>
   //              <times/>
   //              <ci> koff </ci>
   //              <ci> ES </ci>
   //            </apply>
   //          </apply>
   //        </apply>
   //
   //--------------------------------------------

   ASTNode* astMath = new ASTNode(AST_TIMES);
   astMath->addChild(astCytosol);
   astMath->addChild(astMinus);

   //---------------------------------------------
   //
   // set the Math element
   //
   //------------------------------------------------

   kl->setMath(astMath);

  // KineticLaw::setMath(const ASTNode*) sets the math of the KineticLaw object
  // to a copy of the given ASTNode, and thus basically the caller should delete 
  // the original ASTNode object if the caller has the ownership of the object to 
  // avoid memory leak.

   delete astMath;


  //---------------------------------------------------------------------------
  // Creates local Parameter objects inside the KineticLaw object.
  //---------------------------------------------------------------------------

  // Creates a Parameter ("kon")

  Parameter* para = kl->createParameter();
  para->setId("kon");
  para->setValue(1000000);
  para->setUnits("litre_per_mole_per_second");

  // Creates a Parameter ("koff")

  para = kl->createParameter();
  para->setId("koff");
  para->setValue(0.2);
  para->setUnits("per_second");


  //---------------------------------------------------------------------------
  // (Reaction2) Creates a Reaction object ("vcat") .
  //---------------------------------------------------------------------------
  
  reaction = model->createReaction();
  reaction->setId("vcat");
  reaction->setReversible(false);

  //---------------------------------------------------------------------------
  // Creates Reactant objects inside the Reaction object ("vcat"). 
  //---------------------------------------------------------------------------

  // (Reactant1) Creates a Reactant object that references Species "ES" in the
  // model.

  spr = reaction->createReactant();
  spr->setSpecies("ES");

  //---------------------------------------------------------------------------
  // Creates a Product object inside the Reaction object ("vcat"). 
  //---------------------------------------------------------------------------
  
  // (Product1) Creates a Product object that references Species "E" in the model.

  spr = reaction->createProduct();
  spr->setSpecies("E");

  // (Product2) Creates a Product object that references Species "P" in the model.

  spr = reaction->createProduct();
  spr->setSpecies("P");

  //---------------------------------------------------------------------------
  // Creates a KineticLaw object inside the Reaction object ("vcat"). 
  //---------------------------------------------------------------------------
  
  kl = reaction->createKineticLaw();

  //---------------------------------------------------------------------------
  // Sets a math (ASTNode object) to the KineticLaw object.
  //---------------------------------------------------------------------------

  // To create mathematical expressions, one would typically construct
  // an ASTNode tree as the above example code which creates a math of another
  // KineticLaw object.  Here, to save some space and illustrate another approach 
  // of doing it, we will write out the formula in MathML form and then use a 
  // libSBML convenience function to create the ASTNode tree for us.  
  // (This is a bit dangerous; it's very easy to make mistakes when writing MathML 
  // by hand, so in a real program, we would not really want to do it this way.)

  string mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
                         "  <apply>"
                         "    <times/>"
                         "    <ci> cytosol </ci>"
                         "    <ci> kcat </ci>"
                         "    <ci> ES </ci>"
                         "  </apply>"
                         "</math>";

  astMath = readMathMLFromString(mathXMLString.c_str());
  kl->setMath(astMath);
  delete astMath;

  //---------------------------------------------------------------------------
  // Creates local Parameter objects inside the KineticLaw object.
  //---------------------------------------------------------------------------

  // Creates a Parameter ("kcat")

  para = kl->createParameter();
  para->setId("kcat");
  para->setValue(0.1);
  para->setUnits("per_second");


  // Returns the created SBMLDocument object.
  // The returned object must be explicitly deleted by the caller,
  // otherwise a memory leak will happen.

  return sbmlDoc;

}
예제 #17
0
파일: Parser.cpp 프로젝트: meshula/Landru
void parseGlobalVarDecls(CurrPtr& curr, EndPtr end, ASTNode *& currNode
#ifdef LANDRU_HAVE_JSON
    , std::vector<std::pair<std::string, Json::Value*> >* jsonVars
#endif
) 
{
	bool declareBlock = peekToken(curr, end) == kTokenDeclare;
	if (declareBlock) 
    {
		parseDeclare(curr, end, currNode);
		return;
	}

	char name[256];
    char require[256];
    getDeclarator(curr, end, name);

    CurrPtr t = curr;
    if (!getToken(kTokenEq, curr, end)) 
    {
        lcRaiseError("Missing = after global declaration. Eg: \nio = require(\"io\")\n", curr, 32);
    }

    ASTNode* globVar = new ASTNode(kTokenGlobalVariable, name);
    currNode->addChild(globVar);

#ifdef LANDRU_HAVE_JSON
    if (peekChar('{', curr, end) || peekChar('[', curr, end)) 
    {
        const char* jsonStart = curr;

        // Parse a JSON block.
        JSONCallback jsonCallback;
        ASTNode* pop = currNode;
        currNode = new ASTNode(kTokenStaticData);
        globVar->addChild(currNode);
        if (!Lab::Json::parseJsonValue(curr, end, &jsonCallback))
            lcRaiseError("Poorly formed JSON chunk", curr, 32);

        const char* jsonEnd = curr;

        Json::Reader reader;
        Json::Value* root = new Json::Value();
        reader.parse(jsonStart, jsonEnd, *root, false); // false = ignore comments

        jsonVars->push_back(std::pair<std::string, Json::Value*>(name, root));

        currNode = pop;
    }
	else 

#endif
    if (getToken(kTokenRequire, curr, end)) 
    {
        if (getChar('(', curr, end)) 
        {
            curr = tsSkipCommentsAndWhitespace(curr, end);
            char const* value;
            uint32_t length;
            if (*curr == '"') {
                curr = tsGetString(curr, end, true, &value, &length);
                strncpy(require, value, length);
                require[length] = '\0';
            }
            curr = tsSkipCommentsAndWhitespace(curr, end);
            if (!getChar(')', curr, end)) {
                lcRaiseError("Poorly formed require", curr, 32);
            }
        }
        globVar->addChild(new ASTNode(kTokenRequire, require));
    }
    else {
        curr = t;
    }
}
예제 #18
0
 ASTNode *UnaryOp::parse(Parser *parser, Token token) {
     ASTNode *node = new ASTNode(Type,token.Begin);
     node->str = token.String;
     node->addChild(parser->parseExpression()); // parse operand
     return node;
 }
예제 #19
0
ASTNode* CEvaluationNodeLogical::toAST(const CCopasiDataModel* pDataModel) const
{
    SubType subType = (SubType)CEvaluationNode::subType(this->getType());
    ASTNode* node = new ASTNode();

    switch (subType)
    {
    case AND:
        node->setType(AST_LOGICAL_AND);
        break;

    case OR:
        node->setType(AST_LOGICAL_OR);
        break;

    case XOR:
        node->setType(AST_LOGICAL_XOR);
        break;

    case EQ:
        node->setType(AST_RELATIONAL_EQ);
        break;

    case NE:
        node->setType(AST_RELATIONAL_NEQ);
        break;

    case GT:
        node->setType(AST_RELATIONAL_GT);
        break;

    case GE:
        node->setType(AST_RELATIONAL_GEQ);
        break;

    case LT:
        node->setType(AST_RELATIONAL_LT);
        break;

    case LE:
        node->setType(AST_RELATIONAL_LEQ);
        break;

    case INVALID:
        break;

    default:
        subType = INVALID;
        break;
    }

    if (subType != INVALID)
    {
        const CEvaluationNode* child1 = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* child2 = dynamic_cast<const CEvaluationNode*>(child1->getSibling());
        node->addChild(child1->toAST(pDataModel));
        node->addChild(child2->toAST(pDataModel));
    }

    return node;
}
int
ASTPiecewiseFunctionNode::addChild(ASTBase* child, bool inRead)
{
  // now here what I want to do is just keep track of the number
  // of children being added so the mNumPiece and mHasOtherwise
  // variables can be given appropriate values

  // but not if we are reading a stream because then we already know

  if (inRead == false)
  {
    if (child->getType() != AST_CONSTRUCTOR_PIECE && 
        child->getType() != AST_CONSTRUCTOR_OTHERWISE)
    {
      // this child does not have a piece/otherwise but if 
      // the rest of the function does then it needs to fit in with that

      unsigned int currentNum = getNumChildren();

      if (usingChildConstructors() == false)
      {
        if ((currentNum+1)%2 == 0)
        {
          setNumPiece(getNumPiece()+1);
          setHasOtherwise(false);
        }
        else
        {
          setHasOtherwise(true);
        }
     
        return ASTFunctionBase::addChild(child);
      }
      else
      {
        ASTBase * lastChild = 
          ASTFunctionBase::getChild(ASTFunctionBase::getNumChildren()-1);
        if (lastChild == NULL)
        { // we have a serious issue going on but may as well just
          // add the child
          return ASTFunctionBase::addChild(child);
        }
        else if (lastChild->getType() == AST_CONSTRUCTOR_PIECE)
        {
          ASTNode * piece = dynamic_cast<ASTNode*>(lastChild);

          if (piece == NULL)
          {
            return LIBSBML_OPERATION_FAILED;
          }
          if (piece->getNumChildren() == 1)
          {
            return piece->addChild((ASTNode*)(child));
          }
          else
          {
            ASTNode * otherwise = new ASTNode(AST_CONSTRUCTOR_OTHERWISE);
            if (otherwise->addChild((ASTNode*)(child)) == LIBSBML_OPERATION_SUCCESS)
            {
              setHasOtherwise(true);
              return ASTFunctionBase::addChild(otherwise);
            }
            else
            {
              return LIBSBML_OPERATION_FAILED;
            }
          }
        }
        else
        {
          ASTNode * otherwise = dynamic_cast<ASTNode*>(lastChild);

          if (otherwise == NULL || otherwise->getNumChildren() != 1)
          {
            return LIBSBML_OPERATION_FAILED;
          }

          ASTNode * piece = new ASTNode(AST_CONSTRUCTOR_PIECE);
          // add teh child from teh otherwise
          if (piece->addChild(otherwise->getChild(0)) != LIBSBML_OPERATION_SUCCESS)
          {
            return LIBSBML_OPERATION_FAILED;
          }
          else
          {
            if (piece->addChild((ASTNode*)(child)) == LIBSBML_OPERATION_SUCCESS)
            {
              this->removeChild(currentNum-1);
              setHasOtherwise(false);
              setNumPiece(getNumPiece() + 1);
              return ASTFunctionBase::addChild(piece);
            }
            else
            {
              return LIBSBML_OPERATION_FAILED;
            }
          }
        }
      }
    }
    else
    {
      if (child->getType() == AST_CONSTRUCTOR_PIECE)
      {
        setNumPiece(getNumPiece()+1);
      }
      else
      {
        setHasOtherwise(true);
      }
    
      return ASTFunctionBase::addChild(child);
    }
  }
  else
  {
    return ASTFunctionBase::addChild(child);
  }
}
/**
 *
 * Creates an SBML model represented in "7.2 Example involving units"
 * in the SBML Level 2 Version 4 Specification.
 *
 */
SBMLDocument* createExampleInvolvingUnits()
{
  const unsigned int level   = Level;
  const unsigned int version = Version;

  //---------------------------------------------------------------------------
  //
  // Creates an SBMLDocument object 
  //
  //---------------------------------------------------------------------------

  SBMLDocument* sbmlDoc = new SBMLDocument(level,version);

  // Adds the namespace for XHTML to the SBMLDocument object.  We need this
  // because we will add notes to the model.  (By default, the SBML document
  // created by SBMLDocument only declares the SBML XML namespace.)

  sbmlDoc->getNamespaces()->add("http://www.w3.org/1999/xhtml", "xhtml");

  //---------------------------------------------------------------------------
  //
  // Creates a Model object inside the SBMLDocument object. 
  //
  //---------------------------------------------------------------------------

  Model* model = sbmlDoc->createModel();
  model->setId("unitsExample");

  //---------------------------------------------------------------------------
  //
  // Creates UnitDefinition objects inside the Model object.
  //
  //---------------------------------------------------------------------------

  // Temporary pointers (reused more than once below).

  UnitDefinition* unitdef;
  Unit *unit;

  //---------------------------------------------------------------------------  
  // (UnitDefinition1) Creates an UnitDefinition object ("substance").
  //
  // This has the effect of redefining the default unit of subtance for the
  // whole model.
  //---------------------------------------------------------------------------

  unitdef = model->createUnitDefinition();
  unitdef->setId("substance");

  //  Creates an Unit inside the UnitDefinition object 

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_MOLE);
  unit->setScale(-3);

  //--------------------------------------------------------------------------------
  // (UnitDefinition2) Creates an UnitDefinition object ("mmls") 
  //--------------------------------------------------------------------------------
    
  // Note that we can reuse the pointers 'unitdef' and 'unit' because the
  // actual UnitDefinition object (along with the Unit objects within it)
  // is already attached to the Model object.

  unitdef = model->createUnitDefinition();
  unitdef->setId("mmls");
    
  //  Creates an Unit inside the UnitDefinition object ("mmls")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_MOLE);
  unit->setScale(-3);

  //  Creates an Unit inside the UnitDefinition object ("mmls")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_LITRE);
  unit->setExponent(-1);

  //  Creates an Unit inside the UnitDefinition object ("mmls")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_SECOND);
  unit->setExponent(-1);

  //--------------------------------------------------------------------------------
  // (UnitDefinition3) Creates an UnitDefinition object ("mml") 
  //--------------------------------------------------------------------------------
    
  unitdef = model->createUnitDefinition();
  unitdef->setId("mml");
    
  //  Creates an Unit inside the UnitDefinition object ("mml")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_MOLE);
  unit->setScale(-3);

  //  Creates an Unit inside the UnitDefinition object ("mml")

  unit = unitdef->createUnit();
  unit->setKind(UNIT_KIND_LITRE);
  unit->setExponent(-1);


  //---------------------------------------------------------------------------
  //
  // Creates a Compartment object inside the Model object. 
  //
  //---------------------------------------------------------------------------

  Compartment* comp;
  const string compName = "cell";

  // Creates a Compartment object ("cell")

  comp = model->createCompartment();
  comp->setId(compName);
 
  // Sets the "size" attribute of the Compartment object.
  //
  //   The units of this Compartment object is the default SBML 
  //   units of volume (litre), and thus we don't have to explicitly invoke 
  //   setUnits("litre") function to set the default units.
  //
  comp->setSize(1);


  //---------------------------------------------------------------------------
  //
  // Creates Species objects inside the Model object. 
  //
  //---------------------------------------------------------------------------
  
  // Temporary pointer (reused more than once below).
  
  Species *sp;

  //---------------------------------------------------------------------------
  // (Species1) Creates a Species object ("x0")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setId("x0");

  // Sets the "compartment" attribute of the Species object to identify the 
  // compartnet in which the Species object located.

  sp->setCompartment(compName);

  // Sets the "initialConcentration" attribute of the Species object.
  //
  //  The units of this Species object is determined by two attributes of this 
  //  Species object ("substanceUnits" and "hasOnlySubstanceUnits") and the
  //  "spatialDimensions" attribute of the Compartment object ("cytosol") in which 
  //  this species object is located.
  //  Since the default values are used for "substanceUnits" (substance (mole)) 
  //  and "hasOnlySubstanceUnits" (false) and the value of "spatialDimension" (3) 
  //  is greater than 0, the units of this Species object is  moles/liters . 
  //
  sp->setInitialConcentration(1);

  //---------------------------------------------------------------------------
  // (Species2) Creates a Species object ("x1")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setId("x1");
  sp->setCompartment(compName);
  sp->setInitialConcentration(1);

  //---------------------------------------------------------------------------
  // (Species3) Creates a Species object ("s1")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setCompartment(compName);
  sp->setId("s1");
  sp->setInitialConcentration(1);

  //---------------------------------------------------------------------------
  // (Species4) Creates a Species object ("s2")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setCompartment(compName);
  sp->setId("s2");
  sp->setInitialConcentration(1);

  //---------------------------------------------------------------------------
  //
  // Creates global Parameter objects inside the Model object. 
  //
  //---------------------------------------------------------------------------

  Parameter* para;

  // Creates a Parameter ("vm")  

  para = model->createParameter();
  para->setId("vm");
  para->setValue(2);
  para->setUnits("mmls");

  // Creates a Parameter ("km")  

  para = model->createParameter();
  para->setId("km");
  para->setValue(2);
  para->setUnits("mml");


  //---------------------------------------------------------------------------
  //
  // Creates Reaction objects inside the Model object. 
  //
  //---------------------------------------------------------------------------
  
  // Temporary pointers.

  Reaction* reaction;
  SpeciesReference* spr;
  KineticLaw* kl;

  //---------------------------------------------------------------------------
  // (Reaction1) Creates a Reaction object ("v1").
  //---------------------------------------------------------------------------

  reaction = model->createReaction();
  reaction->setId("v1");

  //---------------------------------------------------------------------------
  // Creates Reactant objects inside the Reaction object ("v1"). 
  //---------------------------------------------------------------------------

  // (Reactant1) Creates a Reactant object that references Species "x0"
  // in the model.

  spr = reaction->createReactant();
  spr->setSpecies("x0");

  //---------------------------------------------------------------------------
  // Creates a Product object inside the Reaction object ("v1"). 
  //---------------------------------------------------------------------------

  // Creates a Product object that references Species "s1" in the model. 

  spr = reaction->createProduct();
  spr->setSpecies("s1");

  //---------------------------------------------------------------------------
  // Creates a KineticLaw object inside the Reaction object ("v1"). 
  //---------------------------------------------------------------------------
  
  kl = reaction->createKineticLaw();

  // Creates a <notes> element in the KineticLaw object.
  // Here we illustrate how to do it using a literal string.  This requires
  // known the required syntax of XHTML and the requirements for SBML <notes>
  // elements.  Later below, we show how to create notes using objects instead
  // of strings.

  string notesString = "<xhtml:p> ((vm * s1)/(km + s1)) * cell </xhtml:p>";
  kl->setNotes(notesString);

  //---------------------------------------------------------------------------
  // Creates an ASTNode object which represents the following KineticLaw object.
  //
  //  <math xmlns=\"http://www.w3.org/1998/Math/MathML\">
  //   <apply>
  //     <times/>
  //     <apply>
  //       <divide/>
  //       <apply>
  //         <times/>
  //           <ci> vm </ci>
  //           <ci> s1 </ci>
  //       </apply>
  //       <apply>
  //         <plus/>
  //           <ci> km </ci>
  //           <ci> s1 </ci>
  //       </apply>
  //     </apply>
  //     <ci> cell </ci>
  //    </apply>
  //  </math>
  //---------------------------------------------------------------------------

  //
  // In the following code, ASTNode objects, which construct an ASTNode tree 
  // of the above math, are created and added in the order of preorder traversal 
  // of the tree (i.e. the order corresponds to the nested structure of the above 
  // MathML elements), and thus the following code maybe a bit more efficient but 
  // maybe a bit difficult to read.
  //

  ASTNode* astMath = new ASTNode(AST_TIMES);

  astMath->addChild(new ASTNode(AST_DIVIDE));
  ASTNode* astDivide = astMath->getLeftChild();

  astDivide->addChild(new ASTNode(AST_TIMES));
  ASTNode* astTimes = astDivide->getLeftChild();

  astTimes->addChild(new ASTNode(AST_NAME));
  astTimes->getLeftChild()->setName("vm");

  astTimes->addChild(new ASTNode(AST_NAME));
  astTimes->getRightChild()->setName("s1");

  astDivide->addChild(new ASTNode(AST_PLUS));
  ASTNode* astPlus = astDivide->getRightChild();

  astPlus->addChild(new ASTNode(AST_NAME));
  astPlus->getLeftChild()->setName("km");

  astPlus->addChild(new ASTNode(AST_NAME));
  astPlus->getRightChild()->setName("s1");


  astMath->addChild(new ASTNode(AST_NAME));
  astMath->getRightChild()->setName("cell");

  //---------------------------------------------
  //
  // set the Math element
  //
  //------------------------------------------------

  kl->setMath(astMath);
  delete astMath;


  //---------------------------------------------------------------------------
  // (Reaction2) Creates a Reaction object ("v2").
  //---------------------------------------------------------------------------

  reaction = model->createReaction();
  reaction->setId("v2");

  //---------------------------------------------------------------------------
  // Creates Reactant objects inside the Reaction object ("v2"). 
  //---------------------------------------------------------------------------

  // (Reactant2) Creates a Reactant object that references Species "s1"
  // in the model.

  spr = reaction->createReactant();
  spr->setSpecies("s1");

  //---------------------------------------------------------------------------
  // Creates a Product object inside the Reaction object ("v2"). 
  //---------------------------------------------------------------------------

  // Creates a Product object that references Species "s2" in the model. 

  spr = reaction->createProduct();
  spr->setSpecies("s2");

  //---------------------------------------------------------------------------
  // Creates a KineticLaw object inside the Reaction object ("v2"). 
  //---------------------------------------------------------------------------
  
  kl = reaction->createKineticLaw();

  // Sets a notes (by XMLNode) to the KineticLaw object.
  //
  // The following code is an alternative to using setNotes(const string&).
  // The equivalent code would be like this:
  //   
  //     notesString = "<xhtml:p>((vm * s2)/(km + s2))*cell</xhtml:p>";
  //     kl->setNotes(notesString);

  // Creates an XMLNode of start element (<xhtml:p>) without attributes.

  XMLNode notesXMLNode(XMLTriple("p", "", "xhtml"), XMLAttributes());

  // Adds a text element to the start element.

  notesXMLNode.addChild(XMLNode(" ((vm * s2)/(km + s2)) * cell ")); 

  // Adds it to the kineticLaw object.

  kl->setNotes(&notesXMLNode);

  //---------------------------------------------------------------------------
  // Sets a math (ASTNode object) to the KineticLaw object.
  //---------------------------------------------------------------------------

  // To create mathematical expressions, one would typically construct
  // an ASTNode tree as the above example code which creates a math of another
  // KineticLaw object.  Here, to save some space and illustrate another approach 
  // of doing it, we will write out the formula in MathML form and then use a 
  // libSBML convenience function to create the ASTNode tree for us.  
  // (This is a bit dangerous; it's very easy to make mistakes when writing MathML 
  // by hand, so in a real program, we would not really want to do it this way.)

  string mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
                         "  <apply>"
                         "    <times/>"
                         "    <apply>"
                         "      <divide/>"
                         "      <apply>"
                         "        <times/>"
                         "        <ci> vm </ci>"
                         "        <ci> s2 </ci>"
                         "      </apply>"
                         "      <apply>"
                         "        <plus/>"
                         "          <ci> km </ci>"
                         "          <ci> s2 </ci>"
                         "      </apply>"
                         "    </apply>"
                         "    <ci> cell </ci>"
                         "  </apply>"
                         "</math>";

  astMath = readMathMLFromString(mathXMLString.c_str());
  kl->setMath(astMath);
  delete astMath;


  //---------------------------------------------------------------------------
  // (Reaction3) Creates a Reaction object ("v3").
  //---------------------------------------------------------------------------

  reaction = model->createReaction();
  reaction->setId("v3");

  //---------------------------------------------------------------------------
  // Creates Reactant objects inside the Reaction object ("v3"). 
  //---------------------------------------------------------------------------

  // (Reactant2) Creates a Reactant object that references Species "s2"
  // in the model.

  spr = reaction->createReactant();
  spr->setSpecies("s2");

  //---------------------------------------------------------------------------
  // Creates a Product object inside the Reaction object ("v3"). 
  //---------------------------------------------------------------------------

  // Creates a Product object that references Species "x1" in the model. 

  spr = reaction->createProduct();
  spr->setSpecies("x1");


  //---------------------------------------------------------------------------
  // Creates a KineticLaw object inside the Reaction object ("v3"). 
  //---------------------------------------------------------------------------
  
  kl = reaction->createKineticLaw();

  // Sets a notes (by string) to the KineticLaw object.

  notesString = "<xhtml:p> ((vm * x1)/(km + x1)) * cell </xhtml:p>";
  kl->setNotes(notesString);

  //---------------------------------------------------------------------------
  // Sets a math (ASTNode object) to the KineticLaw object.
  //---------------------------------------------------------------------------

  mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
                  "  <apply>"
                  "    <times/>"
                  "    <apply>"
                  "      <divide/>"
                  "      <apply>"
                  "        <times/>"
                  "        <ci> vm </ci>"
                  "        <ci> x1 </ci>"
                  "      </apply>"
                  "      <apply>"
                  "        <plus/>"
                  "          <ci> km </ci>"
                  "          <ci> x1 </ci>"
                  "      </apply>"
                  "    </apply>"
                  "    <ci> cell </ci>"
                  "  </apply>"
                  "</math>";

  astMath = readMathMLFromString(mathXMLString.c_str());
  kl->setMath(astMath);
  delete astMath;


  // Returns the created SBMLDocument object.
  // The returned object must be explicitly deleted by the caller,
  // otherwise memory leak will happen.

  return sbmlDoc;

}
예제 #22
0
ASTNode* CEvaluationNodeFunction::toAST(const CCopasiDataModel* pDataModel) const
{
    SubType subType = (SubType)this->subType();
    ASTNode* node = new ASTNode();
    bool needFirstArg = true;

    switch (subType)
    {
    case S_INVALID:
        break;

    case S_LOG:
        node->setType(AST_FUNCTION_LN);
        break;

    case S_LOG10:
    {
        // log 10 needs two children, the log and the base
        node->setType(AST_FUNCTION_LOG);

        ASTNode* logBase = new ASTNode();
        logBase->setType(AST_INTEGER);
        logBase->setValue(10);
        node->addChild(logBase);

        break;
    }

    case S_EXP:
        node->setType(AST_FUNCTION_EXP);
        break;

    case S_SIN:
        node->setType(AST_FUNCTION_SIN);
        break;

    case S_COS:
        node->setType(AST_FUNCTION_COS);
        break;

    case S_TAN:
        node->setType(AST_FUNCTION_TAN);
        break;

    case S_SEC:
        node->setType(AST_FUNCTION_SEC);
        break;

    case S_CSC:
        node->setType(AST_FUNCTION_CSC);
        break;

    case S_COT:
        node->setType(AST_FUNCTION_COT);
        break;

    case S_SINH:
        node->setType(AST_FUNCTION_SINH);
        break;

    case S_COSH:
        node->setType(AST_FUNCTION_COSH);
        break;

    case S_TANH:
        node->setType(AST_FUNCTION_TANH);
        break;

    case S_SECH:
        node->setType(AST_FUNCTION_SECH);
        break;

    case S_CSCH:
        node->setType(AST_FUNCTION_CSCH);
        break;

    case S_COTH:
        node->setType(AST_FUNCTION_COTH);
        break;

    case S_ARCSIN:
        node->setType(AST_FUNCTION_ARCSIN);
        break;

    case S_ARCCOS:
        node->setType(AST_FUNCTION_ARCCOS);
        break;

    case S_ARCTAN:
        node->setType(AST_FUNCTION_ARCTAN);
        break;

    case S_ARCSEC:
        node->setType(AST_FUNCTION_ARCSEC);
        break;

    case S_ARCCSC:
        node->setType(AST_FUNCTION_ARCCSC);
        break;

    case S_ARCCOT:
        node->setType(AST_FUNCTION_ARCCOT);
        break;

    case S_ARCSINH:
        node->setType(AST_FUNCTION_ARCSINH);
        break;

    case S_ARCCOSH:
        node->setType(AST_FUNCTION_ARCCOSH);
        break;

    case S_ARCTANH:
        node->setType(AST_FUNCTION_ARCTANH);
        break;

    case S_ARCSECH:
        node->setType(AST_FUNCTION_ARCSECH);
        break;

    case S_ARCCSCH:
        node->setType(AST_FUNCTION_ARCCSCH);
        break;

    case S_ARCCOTH:
        node->setType(AST_FUNCTION_ARCCOTH);
        break;

    case S_SQRT:
        node->setType(AST_FUNCTION_ROOT);
        break;

    case S_ABS:
        node->setType(AST_FUNCTION_ABS);
        break;

    case S_CEIL:
        node->setType(AST_FUNCTION_CEILING);
        break;

    case S_FLOOR:
        node->setType(AST_FUNCTION_FLOOR);
        break;

    case S_FACTORIAL:
        node->setType(AST_FUNCTION_FACTORIAL);
        break;

    case S_MINUS:
        node->setType(AST_MINUS);
        break;

    case S_PLUS:
        // if this is the unary plus as I suspect,
        // the node will be replaced by its only child
        delete node;
        node = dynamic_cast<const CEvaluationNode*>(this->getChild())->toAST(pDataModel);
        break;

    case S_NOT:
        node->setType(AST_LOGICAL_NOT);
        break;

    case S_RUNIFORM:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("RUNIFORM");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        node->addChild(child->toAST(pDataModel));
        node->addChild(sibling->toAST(pDataModel));
    }
    break;

    case S_RNORMAL:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("RNORMAL");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        node->addChild(child->toAST(pDataModel));
        node->addChild(sibling->toAST(pDataModel));
    }
    break;

    case S_RGAMMA:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("RGAMMA");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        node->addChild(child->toAST(pDataModel));
        node->addChild(sibling->toAST(pDataModel));
    }
    break;

    case S_RPOISSON:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("RPOISSON");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        node->addChild(child->toAST(pDataModel));
    }
    break;

    case S_MAX:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("MAX");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        node->addChild(child->toAST(pDataModel));
        node->addChild(sibling->toAST(pDataModel));
    }
    break;

    case S_MIN:
    {
        needFirstArg = false;
        node->setType(AST_FUNCTION);
        node->setName("MIN");
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        node->addChild(child->toAST(pDataModel));
        node->addChild(sibling->toAST(pDataModel));
    }
    break;
        // :TODO: Bug 894: Implement me.
        //fatalError();
    break;
    }

    if (subType != S_INVALID)
    {
        // the following is a workaround for a bug in libsbml 3.1.1 and 3.2.0
        // where libsbml does not handle the case correctly that a root
        // function can have one or two children (MathML.cpp in function
        // writeFunctionRoot)
        if (subType == S_SQRT)
        {
            // add a degree node of value 2 as the first child
            ASTNode* pDegreeNode = new ASTNode();
            pDegreeNode->setType(AST_INTEGER);
            pDegreeNode->setValue(2);
            node->addChild(pDegreeNode);
        }

        if (needFirstArg)
        {
            const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
            node->addChild(child->toAST(pDataModel));
        }
    }

    return node;
}