Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions core/src/org/sbml/jsbml/util/AntimonyConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.sbml.jsbml.util;

/**
* Interface defining constant keywords and operators used in the Antimony scripting language.
* Implementing this interface allows direct inheritance of all constants.
*
* @author Deepak Yadav
*/
public interface AntimonyConstants {
public static final String MODEL = "model ";
public static final String END = "end\n";
public static final String COMPARTMENT = "compartment ";
public static final String SPECIES = "species ";
public static final String SUBSTANCE_ONLY = "substanceOnly species ";
public static final String IN = " in ";
public static final String IRREVERSIBLE = " => ";
public static final String REVERSIBLE = " -> ";
public static final String ASSIGNMENT = " := ";
public static final String RATE = "' = ";
public static final String ALGEBRAIC = "0 = ";
public static final String AT = "at ";
public static final String AFTER = " after ";
public static final String DELAY = ", delay = ";
public static final String PRIORITY = ", priority = ";
public static final String T0_FALSE = ", t0 = false";
public static final String PERSISTENT_FALSE = ", persistent = false";
}
34 changes: 17 additions & 17 deletions core/src/org/sbml/jsbml/util/AntimonySerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*
* @author Deepak Yadav
*/
public class AntimonySerializer {
public class AntimonySerializer implements AntimonyConstants {

/**
* Generic router for UI plugins (e.g., Eclipse, IntelliJ, VSCode).
Expand Down Expand Up @@ -62,7 +62,7 @@ public static String toAntimony(Model model) {
StringBuilder ant = new StringBuilder();

String modelName = model.isSetName() ? model.getName() : model.getId();
ant.append("model ").append(modelName).append("()\n\n");
ant.append(MODEL).append(modelName).append("()\n\n");

ant.append(" // Compartments\n");
for (Compartment c : model.getListOfCompartments()) {
Expand Down Expand Up @@ -94,7 +94,7 @@ public static String toAntimony(Model model) {
}
ant.append("\n");

ant.append("end\n");
ant.append(END);

return ant.toString();
}
Expand All @@ -105,7 +105,7 @@ public static String toAntimony(Model model) {
public static String toAntimony(Compartment c) {
if (c == null) return "";
StringBuilder ant = new StringBuilder();
ant.append("compartment ").append(c.getId());
ant.append(COMPARTMENT).append(c.getId());
if (c.isSetSize()) {
ant.append(" = ").append(c.getSize());
}
Expand All @@ -126,9 +126,9 @@ public static String toAntimony(Species s) {

// 1. Handle Substance Units
if (hOSU) {
ant.append("substanceOnly species ");
ant.append(SUBSTANCE_ONLY);
} else {
ant.append("species ");
ant.append(SPECIES);
}

// 2. Handle Boundary Condition
Expand All @@ -140,7 +140,7 @@ public static String toAntimony(Species s) {

// Compartment assignment
if (s.isSetCompartment()) {
ant.append(" in ").append(s.getCompartment());
ant.append(IN).append(s.getCompartment());
}

// 3. Handle Initial Values based on Concentration vs Amount assumptions
Expand Down Expand Up @@ -194,9 +194,9 @@ public static String toAntimony(Reaction r) {

// 3. Reversibility (Antimony uses -> for reversible, => for irreversible)
if (r.isSetReversible() && !r.getReversible()) {
ant.append(" => ");
ant.append(IRREVERSIBLE);
} else {
ant.append(" -> ");
ant.append(REVERSIBLE);
}

// 4. Products
Expand Down Expand Up @@ -236,11 +236,11 @@ public static String toAntimony(Rule r) {
String math = ASTNode.formulaToString(r.getMath());

if (r instanceof AssignmentRule) {
return ((AssignmentRule) r).getVariable() + " := " + math + ";";
return ((AssignmentRule) r).getVariable() + ASSIGNMENT + math + ";";
} else if (r instanceof RateRule) {
return ((RateRule) r).getVariable() + "' = " + math + ";";
return ((RateRule) r).getVariable() + RATE + math + ";";
} else if (r instanceof AlgebraicRule) {
return "0 = " + math + ";";
return ALGEBRAIC + math + ";";
}

return "// Unsupported Rule type.";
Expand All @@ -258,29 +258,29 @@ public static String toAntimony(Event e) {
ant.append(e.getId()).append(": ");
}

ant.append("at ");
ant.append(AT);
boolean hasTrigger = e.isSetTrigger() && e.getTrigger().isSetMath();
boolean hasDelay = e.isSetDelay() && e.getDelay().isSetMath();

if (hasDelay && hasTrigger) {
ant.append(ASTNode.formulaToString(e.getDelay().getMath()));
ant.append(" after ");
ant.append(AFTER);
ant.append(ASTNode.formulaToString(e.getTrigger().getMath()));
} else if (hasTrigger) {
ant.append(ASTNode.formulaToString(e.getTrigger().getMath()));
}

// Advanced Event Options
if (e.isSetPriority() && e.getPriority().isSetMath()) {
ant.append(", priority = ").append(ASTNode.formulaToString(e.getPriority().getMath()));
ant.append(PRIORITY).append(ASTNode.formulaToString(e.getPriority().getMath()));
}
if (e.isSetTrigger()) {
org.sbml.jsbml.Trigger t = e.getTrigger();
if (t.isSetInitialValue() && !t.getInitialValue()) {
ant.append(", t0 = false");
ant.append(T0_FALSE);
}
if (t.isSetPersistent() && !t.getPersistent()) {
ant.append(", persistent = false");
ant.append(PERSISTENT_FALSE);
}
}
ant.append(": ");
Expand Down
33 changes: 33 additions & 0 deletions core/test/org/sbml/jsbml/util/AntimonyConstantsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.sbml.jsbml.util;

import org.junit.Test;
import static org.junit.Assert.assertEquals;

/**
* Tests for the {@link AntimonyConstants} interface.
* Ensures that core Antimony keywords and operators remain safely unchanged
* to prevent parser regressions.
*
* @author Deepak Yadav
*/

public class AntimonyConstantsTest {

@Test
public void testCoreConstants() {
// Verify that the core structural constants haven't been accidentally altered
assertEquals("model ", AntimonyConstants.MODEL);
assertEquals("end\n", AntimonyConstants.END);
assertEquals("species ", AntimonyConstants.SPECIES);
assertEquals("compartment ", AntimonyConstants.COMPARTMENT);
}

@Test
public void testOperatorConstants() {
// Verify reaction and assignment operators
assertEquals(" => ", AntimonyConstants.IRREVERSIBLE);
assertEquals(" -> ", AntimonyConstants.REVERSIBLE);
assertEquals(" := ", AntimonyConstants.ASSIGNMENT);
assertEquals("' = ", AntimonyConstants.RATE);
}
}