David Nickerson wrote:
> I have attached two implementations of the same equation, y = sin(x).
>
> In the case where the equation is given in a component within the same 
> model as its parent in the encapsulation hierarchy (import_bug-ok.xml) 
> everything works fine and CellML2C gives me the expected code.
>
> If I move the exact same component to a separate model (sin.xml) and 
> import it (import_bug-fail.xml) then CellML2C tells me the model is 
> now overconstrained. But as far as I can tell it is the exact same model.
>
> Can anyone spot an obvious mistake or is this a bug in the CCGS?
It was a bug in the CCGS. Thanks for the report and the test-case (which 
has now been included as a regression test for CCGS). This has been 
fixed in revision 1014 on the trunk. Patch follows...

Index: CCGS/sources/CCGSGenerator.cpp
===================================================================
--- CCGS/sources/CCGSGenerator.cpp      (revision 1013)
+++ CCGS/sources/CCGSGenerator.cpp      (revision 1014)
@@ -10,16 +10,54 @@
 // Win32 hack...
 #ifdef _WIN32
 #define swprintf _snwprintf
 #endif

 #include "CodeGenerationError.hxx"
 #include "TemporaryAnnotation.hxx"

+iface::cellml_api::CellMLComponent*
+GetRealComponent(iface::cellml_api::CellMLElement* in)
+{
+  DECLARE_QUERY_INTERFACE_OBJREF(x, in, cellml_api::CellMLComponent);
+  if (x == NULL)
+    throw CodeGenerationError(L"\"in\" not a component (bug)");
+  while (true)
+  {
+    DECLARE_QUERY_INTERFACE_OBJREF(imp, x, cellml_api::ImportComponent);
+    if (imp == NULL)
+    {
+      x->add_ref();
+      return x;
+    }
+    RETURN_INTO_OBJREF(cee, iface::cellml_api::CellMLElement,
+                       imp->parentElement());
+    DECLARE_QUERY_INTERFACE_OBJREF(cei, cee, cellml_api::CellMLImport);
+    if (cei == NULL)
+      throw CodeGenerationError(L"Parent of import component not import.");
+    RETURN_INTO_OBJREF(im, iface::cellml_api::Model, cei->importedModel());
+    RETURN_INTO_OBJREF(cs, iface::cellml_api::CellMLComponentSet,
+                       im->modelComponents());
+    RETURN_INTO_OBJREF(ci, iface::cellml_api::CellMLComponentIterator,
+                       cs->iterateComponents());
+    RETURN_INTO_WSTRING(tn, imp->componentRef());
+    while (true)
+    {
+      x = already_AddRefd<iface::cellml_api::CellMLComponent>
+        (ci->nextComponent());
+      if (x == NULL)
+        throw CodeGenerationError(L"Imported component missing");
+      RETURN_INTO_WSTRING(n, x->name());
+      if (n == tn)
+        break;
+    }
+  }
+}
+
 static struct
 {
   uint32_t badmask;
   const wchar_t* errMsg;
 }  IncompatibleFlagSet[] =
 {
   {
     VariableInformation::SUBJECT_OF_DIFF |
@@ -189,24 +227,26 @@ CodeGenerationState::CreateComponentList
   RETURN_INTO_OBJREF(ci, iface::cellml_api::CellMLComponentIterator,
                      mc->iterateComponents());
   while (true)
   {
     RETURN_INTO_OBJREF(c, iface::cellml_api::CellMLComponent,
                        ci->nextComponent());
     if (c == NULL)
       break;
+    RETURN_INTO_OBJREF(rc, iface::cellml_api::CellMLComponent,
+                       GetRealComponent(c));
     // Append the component to the component list...
-    if (compset.count(c) != 0)
+    if (compset.count(rc) != 0)
       continue;
-    c->add_ref();
-    mComponentList.push_back(c);
-    compset.insert(c);
+    rc->add_ref();
+    mComponentList.push_back(rc);
+    compset.insert(rc);
     // Also, any encapsulation descendents go on the list...
-    AddEncapsulationDescendentComponents(compset, c);
+    AddEncapsulationDescendentComponents(compset, rc);
   }
 }

 void
 CodeGenerationState::AddEncapsulationDescendentComponents
 (
  std::set<iface::cellml_api::CellMLComponent*,XPCOMComparator>& compset,
  iface::cellml_api::CellMLComponent* aComponent
@@ -217,24 +257,27 @@ CodeGenerationState::AddEncapsulationDes
   RETURN_INTO_OBJREF(ci, iface::cellml_api::CellMLComponentIterator,
                      cs->iterateComponents());
   while (true)
   {
     RETURN_INTO_OBJREF(c, iface::cellml_api::CellMLComponent,
                        ci->nextComponent());
     if (c == NULL)
       break;
-
-    if (compset.count(c) != 0)
+
+    RETURN_INTO_OBJREF(rc, iface::cellml_api::CellMLComponent,
+                       GetRealComponent(c));
+
+    if (compset.count(rc) != 0)
       continue;

-    c->add_ref();
-    mComponentList.push_back(c);
-    compset.insert(c);
-    AddEncapsulationDescendentComponents(compset, c);
+    rc->add_ref();
+    mComponentList.push_back(rc);
+    compset.insert(rc);
+    AddEncapsulationDescendentComponents(compset, rc);
   }
 }

 void
 CodeGenerationState::ProcessMath()
 {
   std::list<iface::cellml_api::CellMLComponent*>::iterator i;
   for (i = mComponentList.begin(); i != mComponentList.end(); i++)
@@ -697,54 +740,16 @@ CodeGenerationState::DetermineRateVariab

 bool IsPlainCI(iface::mathml_dom::MathMLElement* aSubExpr)
 {
   DECLARE_QUERY_INTERFACE_OBJREF(aCISub, aSubExpr,
                                  mathml_dom::MathMLCiElement);
   return (aCISub != NULL);
 }

-iface::cellml_api::CellMLComponent*
-GetRealComponent(iface::cellml_api::CellMLElement* in)
-{
-  DECLARE_QUERY_INTERFACE_OBJREF(x, in, cellml_api::CellMLComponent);
-  if (x == NULL)
-    throw CodeGenerationError(L"\"in\" not a component (bug)");
-  while (true)
-  {
-    DECLARE_QUERY_INTERFACE_OBJREF(imp, x, cellml_api::ImportComponent);
-    if (imp == NULL)
-    {
-      x->add_ref();
-      return x;
-    }
-    RETURN_INTO_OBJREF(cee, iface::cellml_api::CellMLElement,
-                       imp->parentElement());
-    DECLARE_QUERY_INTERFACE_OBJREF(cei, cee, cellml_api::CellMLImport);
-    if (cei == NULL)
-      throw CodeGenerationError(L"Parent of import component not import.");
-    RETURN_INTO_OBJREF(im, iface::cellml_api::Model, cei->importedModel());
-    RETURN_INTO_OBJREF(cs, iface::cellml_api::CellMLComponentSet,
-                       im->modelComponents());
-    RETURN_INTO_OBJREF(ci, iface::cellml_api::CellMLComponentIterator,
-                       cs->iterateComponents());
-    RETURN_INTO_WSTRING(tn, imp->componentRef());
-    while (true)
-    {
-      x = already_AddRefd<iface::cellml_api::CellMLComponent>
-        (ci->nextComponent());
-      if (x == NULL)
-        throw CodeGenerationError(L"Imported component missing");
-      RETURN_INTO_WSTRING(n, x->name());
-      if (n == tn)
-        break;
-    }
-  }
-}
-
 double
 CodeGenerationState::GetConversion
 (
  iface::cellml_api::CellMLVariable* vfrom,
  iface::cellml_api::CellMLVariable* vto,
  double& offset
 )
 {
Index: tests/CheckCodeGenerator
===================================================================
--- tests/CheckCodeGenerator    (revision 1013)
+++ tests/CheckCodeGenerator    (revision 1014)
@@ -39,10 +39,11 @@ function runtest()
   rm -f $TEMPFILE
 }

 runtest cellml_simple_test
 runtest modified_parabola
 runtest underconstrained_1
 runtest overconstrained_1
 runtest newton_raphson_parabola
+runtest import_eqn

 exit 0
Index: tests/test_xml/imported_eqn.xml
===================================================================
--- tests/test_xml/imported_eqn.xml     (revision 0)
+++ tests/test_xml/imported_eqn.xml     (revision 1014)
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<model
+    name="sin"
+    cmeta:id="sin"
+    xmlns="http://www.cellml.org/cellml/1.1#";
+    xmlns:cellml="http://www.cellml.org/cellml/1.1#";
+    xmlns:cmeta="http://www.cellml.org/metadata/1.0#";>
+  <rdf:RDF
+      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+      xmlns:cmeta="http://www.cellml.org/metadata/1.0#";
+      xmlns:bqs="http://www.cellml.org/bqs/1.0#";
+      xmlns:dc="http://purl.org/dc/elements/1.1/";
+      xmlns:dcterms="http://purl.org/dc/terms/";
+      xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#";
+      xmlns:cs="http://www.cellml.org/metadata/simulation/1.0#";
+      xmlns:cg="http://www.cellml.org/metadata/graphs/1.0#";>
+    <rdf:Description rdf:about="">
+      <dc:creator rdf:parseType="Resource">
+        <vCard:N rdf:parseType="Resource">
+          <vCard:Family>Nickerson</vCard:Family>
+          <vCard:Given>David</vCard:Given>
+        </vCard:N>
+        <vCard:EMAIL rdf:parseType="Resource">
+          <rdf:value>[EMAIL PROTECTED]</rdf:value>
+          <rdf:type rdf:resource="http://imc.org/vCard/3.0#internet"; />
+        </vCard:EMAIL>
+        <vCard:ORG rdf:parseType="Resource">
+          <vCard:Orgname>National University of Singapore</vCard:Orgname>
+          <vCard:Orgunit>Division of Bioengineering</vCard:Orgunit>
+        </vCard:ORG>
+      </dc:creator>
+      <dcterms:created rdf:parseType="Resource">
+        <dcterms:W3CDTF>2006-12-21</dcterms:W3CDTF>
+      </dcterms:created>
+    </rdf:Description>
+    <rdf:Description rdf:about="#sin">
+      <dc:title>
+        Simple sine model..
+      </dc:title>
+      <cmeta:comment rdf:parseType="Resource">
+        <rdf:value>
+          A very simple model.
+        </rdf:value>
+        <dc:creator rdf:parseType="Resource">
+          <vCard:FN>David Nickerson</vCard:FN>
+        </dc:creator>
+      </cmeta:comment>
+    </rdf:Description>
+  </rdf:RDF>
+
+  <component name="actual_sin" cmeta:id="actual_sin">
+    <variable name="x" units="dimensionless" public_interface="in" 
private_interface="out"/>
+    <variable cmeta:id="actual_sin" name="sin" units="dimensionless" 
public_interface="out" private_interface="out"/>
+    <math cmeta:id="sin_calculation" 
xmlns="http://www.w3.org/1998/Math/MathML";>
+      <apply id="actual_sin"><eq/>
+        <ci>sin</ci>
+        <apply><sin/>
+          <ci>x</ci>
+        </apply>
+      </apply>
+    </math>
+  </component>
+
+</model>
Index: tests/test_xml/import_eqn.xml
===================================================================
--- tests/test_xml/import_eqn.xml       (revision 0)
+++ tests/test_xml/import_eqn.xml       (revision 1014)
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<model
+    name="sin_approximations_import"
+    cmeta:id="sin_approximations_import"
+    xmlns="http://www.cellml.org/cellml/1.1#";
+    xmlns:cellml="http://www.cellml.org/cellml/1.1#";
+    xmlns:cmeta="http://www.cellml.org/metadata/1.0#";
+    xmlns:xlink="http://www.w3.org/1999/xlink";>
+
+  <import xlink:href="imported_eqn.xml">
+    <component name="actual_sin" component_ref="actual_sin"/>
+  </import>
+
+  <component name="main" cmeta:id="main">
+    <variable cmeta:id="x" name="x" initial_value="0" 
units="dimensionless" public_interface="out" private_interface="out"/>
+    <variable cmeta:id="sin" name="sin1" units="dimensionless" 
public_interface="out" private_interface="in"/>
+  </component>
+
+  <group>
+    <relationship_ref relationship="encapsulation"/>
+    <component_ref component="main">
+      <component_ref component="actual_sin"/>
+    </component_ref>
+  </group>
+
+  <connection>
+    <map_components component_1="actual_sin" component_2="main"/>
+    <map_variables variable_1="sin" variable_2="sin1"/>
+    <map_variables variable_1="x" variable_2="x"/>
+  </connection>
+
+</model>
Index: tests/test_expected/import_eqn.c
===================================================================
--- tests/test_expected/import_eqn.c    (revision 0)
+++ tests/test_expected/import_eqn.c    (revision 1014)
@@ -0,0 +1,32 @@
+/* Model is correctly constrained.
+ * No equations needed Newton-Raphson evaluation.
+ * The main variable array needs 1 entries.
+ * The rate array needs 0 entries.
+ * The constant array needs 1 entries.
+ * The bound array needs 0 entries.
+ * Variable storage is as follows:
+ * * Variable sin in component actual_sin
+ * * * Variable type: computed once
+ * * * Variable index: 0
+ * * * Has differential: false
+ * * Variable x in component main
+ * * * Variable type: constant
+ * * * Variable index: 0
+ * * * Has differential: false
+ */
+void SetupFixedConstants(double* CONSTANTS)
+{
+CONSTANTS[0] = 0;
+}
+void SetupComputedConstants(double* CONSTANTS, double* VARIABLES)
+{
+VARIABLES[0] = sin(CONSTANTS[0]);
+}
+void ComputeRates(double* BOUND, double* RATES, double* CONSTANTS, 
double* VARIABLES)
+{
+}
+void ComputeVariables(double* BOUND, double* RATES, double* CONSTANTS, 
double* VARIABLES)
+{
+#ifndef VARIABLES_FOR_RATES_ONLY
+#endif
+}

_______________________________________________
cellml-discussion mailing list
[email protected]
http://www.cellml.org/mailman/listinfo/cellml-discussion

Reply via email to