diff --git a/models/ht_neuron.nestml b/models/ht_neuron.nestml index 5689b8825..d47775027 100644 --- a/models/ht_neuron.nestml +++ b/models/ht_neuron.nestml @@ -132,9 +132,18 @@ neuron ht_neuron_nestml: D_thresh real = -10.0 D_slope real = 5.0; alias D_influx real = 1.0 / ( 1.0 + exp( -( V_m - D_thresh ) / D_slope ) ); + + alias I_Na real = -g_NaL * ( V_m - E_Na ) + alias I_K real = -g_KL * ( V_m - E_K ) end equations: + # delta V + V_m' = ( I_Na + I_K + I_syn + I_NaP + I_KNa + I_T + I_h + I_stim ) / Tau_m + I_spike + + # delta Theta + THETA' = -( THETA - Theta_eq ) / Tau_theta + # equation modified from y[](1-D_eq) to (y[]-D_eq), since we'd not # be converging to equilibrium otherwise IKNa_D' = D_influx_peak * D_influx - ( IKNa_D - KNa_D_EQ ) / tau_D diff --git a/src/main/java/org/nest/nestml/_symboltable/NESTMLSymbolTableCreator.java b/src/main/java/org/nest/nestml/_symboltable/NESTMLSymbolTableCreator.java index 0cf9505d4..4bb8c4873 100644 --- a/src/main/java/org/nest/nestml/_symboltable/NESTMLSymbolTableCreator.java +++ b/src/main/java/org/nest/nestml/_symboltable/NESTMLSymbolTableCreator.java @@ -7,6 +7,7 @@ import de.monticore.symboltable.*; import de.se_rwth.commons.Names; +import de.se_rwth.commons.logging.Log; import org.nest.nestml._ast.*; import org.nest.nestml._visitor.NESTMLVisitor; import org.nest.ode._ast.ASTEquation; @@ -82,7 +83,7 @@ public void visit(final ASTNESTMLCompilationUnit compilationUnitAst) { private List computeImportStatements(ASTNESTMLCompilationUnit compilationUnitAst) { final List imports = new ArrayList<>(); - compilationUnitAst.getImports().stream().forEach(importStatement -> { + compilationUnitAst.getImports().forEach(importStatement -> { final String importAsString = Names.getQualifiedName(importStatement.getQualifiedName().getParts()); imports.add(new ImportStatement(importAsString, importStatement.isStar())); }); @@ -115,6 +116,7 @@ public void visit(final ASTNeuron astNeuron) { public void endVisit(final ASTNeuron astNeuron) { addVariablesFromODEBlock(astNeuron.getBody()); + assignOdeToVariables(astNeuron.getBody()); removeCurrentScope(); currentTypeSymbol = empty(); } @@ -135,12 +137,12 @@ private void addVariablesFromODEBlock(final ASTBody astBody) { astBody.getODEBlock().get().getODEs() .stream() .filter(ode -> ode.getLhs().getDifferentialOrder().size() > 1) - .forEach(this::addODEVariable); + .forEach(this::addDerivedVariable); } } - private void addODEVariable(final ASTEquation ode) { + private void addDerivedVariable(final ASTEquation ode) { final String variableName = convertToSimpleName(ode.getLhs()); final TypeSymbol type = PredefinedTypes.getType("real"); @@ -151,6 +153,7 @@ private void addODEVariable(final ASTEquation ode) { var.setDeclaringType(currentTypeSymbol.get()); var.setLoggable(true); var.setAlias(false); + //var.setDeclaringExpression(ode.getRhs()); var.setBlockType(VariableSymbol.BlockType.STATE); @@ -159,6 +162,32 @@ private void addODEVariable(final ASTEquation ode) { trace("Adds new shape variable '" + var.getFullName() + "'.", LOGGER_NAME); } + private void assignOdeToVariables(final ASTBody astBody) { + if (astBody.getODEBlock().isPresent()) { + astBody.getODEBlock().get().getODEs() + .stream() + .forEach(this::addOdeToVariable); + + } + + } + + private void addOdeToVariable(final ASTEquation ode) { + checkState(this.currentScope().isPresent()); + + final Scope scope = currentScope().get(); + final String variableName = convertToSimpleName(ode.getLhs()); + final Optional stateVariable = scope.resolve(variableName, VariableSymbol.KIND); + + if (stateVariable.isPresent()) { + stateVariable.get().setOdeDeclaration(ode.getRhs()); + } + else { + Log.warn("NESTMLSymbolTableCreator: The left side of the ode is undefined. Cannot assign its definition: " + variableName); + } + + } + public void visit(final ASTComponent componentAst) { final NeuronSymbol componentSymbol = new NeuronSymbol(componentAst.getName(), COMPONENT); currentTypeSymbol = of(componentSymbol); diff --git a/src/main/java/org/nest/symboltable/symbols/VariableSymbol.java b/src/main/java/org/nest/symboltable/symbols/VariableSymbol.java index c09063860..6cb85229d 100644 --- a/src/main/java/org/nest/symboltable/symbols/VariableSymbol.java +++ b/src/main/java/org/nest/symboltable/symbols/VariableSymbol.java @@ -9,9 +9,7 @@ import de.monticore.symboltable.Scope; import de.monticore.symboltable.SymbolKind; import org.nest.commons._ast.ASTExpr; -import org.nest.nestml._ast.ASTInput; import org.nest.nestml._ast.ASTInputLine; -import org.nest.nestml._ast.ASTInputType; import org.nest.utils.ASTUtils; import java.util.Objects; @@ -33,6 +31,8 @@ public class VariableSymbol extends CommonSymbol { private ASTExpr declaringExpression = null; + private ASTExpr odeDeclaration = null; + private TypeSymbol type; private NeuronSymbol declaringType; @@ -49,12 +49,21 @@ public boolean isBuffer() { return blockType == BlockType.INPUT_BUFFER_CURRENT || blockType == BlockType.INPUT_BUFFER_SPIKE; } + @SuppressWarnings({"unused"}) // used in templates public boolean isLoggable() { // TODO: check whether the logic is correct. At the moment, the vector datatypes are not supported by the code // generator. return isLoggable && !isVector(); } + public void setOdeDeclaration(final ASTExpr odeDeclaration) { + this.odeDeclaration = odeDeclaration; + } + + public boolean definedByODE() { + return odeDeclaration != null; + } + public void setLoggable(boolean loggable) { isLoggable = loggable; } @@ -177,6 +186,7 @@ public void setBlockType(BlockType blockType) { this.blockType = blockType; } + @SuppressWarnings({"unused"}) // used in templates public boolean hasSetter() { checkState(getAstNode().isPresent(), "Symbol table must set the AST node."); checkArgument(getAstNode().get().getEnclosingScope().isPresent(), "Run symboltable creator."); @@ -184,6 +194,7 @@ public boolean hasSetter() { return isSetterPresent(getName(), getType().getName(), getAstNode().get().getEnclosingScope().get()); } + @SuppressWarnings({"unused"}) // used in templates public String printComment() { final StringBuffer output = new StringBuffer(); if(getAstNode().isPresent()) {