Skip to content

Commit

Permalink
Merge pull request #216 from DimitriPlotnikov/master
Browse files Browse the repository at this point in the history
Prepare release
  • Loading branch information
Plotnikov authored Jul 18, 2016
2 parents a79ecc3 + d2aa8fa commit 7dc111e
Show file tree
Hide file tree
Showing 18 changed files with 122 additions and 31 deletions.
6 changes: 3 additions & 3 deletions models/ht_neuron.nestml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ neuron ht_neuron_nestml:
G_NMDA nS
G_GABA_A nS
G_GABA_B nS
IKNa_D pA
IKNa_D pA = KNa_D_EQ
IT_m pA
IT_h pA
Ih_m pA
Expand All @@ -97,7 +97,7 @@ neuron ht_neuron_nestml:

# The spike current is only activate immediately after a spike.
# TODO const double_t I_spike = node.S_.g_spike_ ? -( V - node.P_.E_K ) / node.P_.Tau_spike : 0;
alias I_spike mV = 0
alias I_spike mV = (g_spike) ? -( V_m - E_K ) / Tau_spike : 0;

# intrinsic currents
# I_Na(p), m_inf^3 according to Compte et al, J Neurophysiol 2003 89:2707
Expand Down Expand Up @@ -188,7 +188,7 @@ neuron ht_neuron_nestml:
T_E_rev mV = 0.0mV
h_g_peak real = 1.0
h_E_rev mV = -40.0mV
KNa_D_EQ real = 0.001;
KNa_D_EQ pA = 0.001pA;
end

internal:
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>nestml</groupId>
<artifactId>nestml-core</artifactId>
<version>0.1.1-SNAPSHOT</version>
<version>0.1.1</version>

<properties>
<!-- .. Libraries ..................................................... -->
Expand Down
1 change: 1 addition & 0 deletions src/main/grammars/org/nest/Commons.mc4
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ grammar Commons extends de.monticore.types.Types {
| logicalNot:["not"] Expr
| left:Expr logicalAnd:["and"] right:Expr
| left:Expr logicalOr:["or"] right:Expr
| condition:Expr "?" ifTure:Expr ":" ifNot:Expr
| FunctionCall
| BooleanLiteral // true & false;
| NESTMLNumericLiteral
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@
public class GSLReferenceConverter implements IReferenceConverter {

private static final String INDEX_VARIABLE_POSTFIX = "_INDEX";
private final boolean isUseUpperBound;
private static final Double MAXIMAL_EXPONENT = 10.0;

public GSLReferenceConverter() {
isUseUpperBound = false; // TODO make it parametrizable
}

@Override
public String convertBinaryOperator(String binaryOperator) {
if (binaryOperator.equals("**")) {
Expand All @@ -39,8 +44,17 @@ public String convertBinaryOperator(String binaryOperator) {
@Override
public String convertFunctionCall(final ASTFunctionCall astFunctionCall) {
final String functionName = astFunctionCall.getCalleeName();

if ("exp".equals(functionName)) {
return "std::exp(std::min(%s, " + MAXIMAL_EXPONENT + "))";

if (isUseUpperBound) {
return "std::exp(std::min(%s, " + MAXIMAL_EXPONENT + "))";
}
else {
return "std::exp(%s)";

}

}
if ("pow".equals(functionName)) {
return "pow(%s)";
Expand All @@ -56,8 +70,7 @@ public String convertNameReference(final ASTVariable astVariable) {
final Scope scope = astVariable.getEnclosingScope().get();
final VariableSymbol variableSymbol = VariableSymbol.resolve(convertDevrivativeNameToSimpleName(astVariable), scope);

if (variableSymbol.getBlockType().equals(VariableSymbol.BlockType.STATE) &&
!variableSymbol.isAlias()) {
if (variableSymbol.definedByODE()) {
return "y[" + variableName + INDEX_VARIABLE_POSTFIX + "]";
}
else {
Expand Down
15 changes: 14 additions & 1 deletion src/main/java/org/nest/nestml/_ast/ASTBody.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ public List<ASTEquation> getEquations() {
}
}

@SuppressWarnings("unused") // used in freemarker templates
public List<VariableSymbol> variablesDefinedByODE() {
return getStateSymbols()
.stream()
.filter(VariableSymbol::definedByODE)
.collect(toList());
}

private Optional<ASTEquations> findEquationsBlock() {
final Optional<ASTBodyElement> equations = this.getBodyElements()
.stream()
Expand All @@ -161,7 +169,12 @@ private String printBlockComment(final Optional<? extends ASTNode> block) {

// STATE variables handling
public List<VariableSymbol> getStateSymbols() {
return getVariableSymbols(getDeclarationsFromBlock(ASTVar_Block::isState), getEnclosingScope().get());
return this.getEnclosingScope().get().resolveLocally(VariableSymbol.KIND)
.stream()
.map(stateSymbol -> (VariableSymbol) stateSymbol)
.filter(VariableSymbol::isState)
.collect(toList());

}

public List<VariableSymbol> getStateAliasSymbols() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ private void addDerivedVariable(final ASTEquation ode) {

private void assignOdeToVariables(final ASTBody astBody) {
if (astBody.getODEBlock().isPresent()) {
astBody.getODEBlock().get().getODEs()
.stream()
astBody.getODEBlock().get()
.getODEs()
.forEach(this::addOdeToVariable);

}
Expand All @@ -174,8 +174,8 @@ private void assignOdeToVariables(final ASTBody astBody) {

private void addOdeToVariable(final ASTEquation ode) {
checkState(this.currentScope().isPresent());

final Scope scope = currentScope().get();

final String variableName = convertToSimpleName(ode.getLhs());
final Optional<VariableSymbol> stateVariable = scope.resolve(variableName, VariableSymbol.KIND);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,14 @@ else if (expr.isLogicalOr() || expr.isLogicalAnd()) {
else if (expr.isLogicalNot()) {
return "not " + print(expr.getExpr().get());
}
else if (expr.getCondition().isPresent()) {
final String condition = print(expr.getCondition().get());
final String ifTrue = print(expr.getIfTure().get()); // guaranteed by grammar
final String ifNot = print(expr.getIfNot().get()); // guaranteed by grammar
return "(" + condition + ")?(" + ifTrue + "):(" + ifNot + ")";
}

final String errorMsg = "Unsupported grammar element. PrettyPrinter must be fixed " + expr.get_SourcePositionStart() + "}";
final String errorMsg = "Unsupported grammar element: PrettyPrinter must be fixed " + expr.get_SourcePositionStart();

throw new RuntimeException(errorMsg);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,30 @@ else if (expr.isLogicalAnd() || expr.isLogicalOr()) {
}

}
else if (expr.getCondition().isPresent()) {

final Either<TypeSymbol, String> condition = computeType(expr.getCondition().get());
final Either<TypeSymbol, String> ifTrue = computeType(expr.getIfTure().get()); // guaranteed by the grammar
final Either<TypeSymbol, String> ifNot = computeType(expr.getIfNot().get()); // guaranteed by the grammar

if (condition.isError()) {
return condition;
}
if (ifTrue.isError()) {
return ifTrue;
}

if (ifNot.isError()) {
return ifNot;
}
if (!condition.getValue().equals(getBooleanType())) {
return Either.error("The ternary operator condition must be a boolean: " + ASTUtils.toString(expr) + ". And not a: " + condition.getValue());
}
if (!isCompatible(ifTrue.getValue(), (ifNot.getValue()))) {
return Either.error("The ternary operator results must be of the same type: " + ASTUtils.toString(expr) + ". And not: " + ifTrue.getValue() + " and " + ifNot.getValue());
}
return ifTrue;
}

final String errorMsg = "This operation for expressions is not supported yet.";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
<#assign ODEs = ast.getEquations()>
<#assign index = 0>
<#assign indexPostfix = "INDEX">
<#list ast.getStateNonAliasSymbols() as stateVariable>
const int ${stateVariable.getName()}_${indexPostfix} = ${index};
<#assign index = index + 1>

<#list ast.variablesDefinedByODE() as odeVariable>
const int ${odeVariable.getName()}_${indexPostfix} = ${index};
<#assign index = index + 1>
</#list>

extern "C" inline int
Expand Down
21 changes: 10 additions & 11 deletions src/main/resources/org/nest/spl/ODEDeclaration.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,21 @@
@param stateSize number of the step variables
@result TODO
-->
<#assign stateSize = body.getStateNonAliasSymbols()?size>
<#assign stateSize = body.getEquations()?size>
<#assign indexPostfix = "INDEX">

double step_ = nest::Time::get_resolution().get_ms();
double IntegrationStep_ = nest::Time::get_resolution().get_ms();
double t = 0;

while ( t < step_ )
{

double stateVector[${stateSize}];
<#assign index = 0>
<#list body.getStateNonAliasSymbols() as stateVariable>
stateVector[${stateVariable.getName()}_${indexPostfix}] = S_.${stateVariable.getName()};
<#list body.variablesDefinedByODE() as odeVariable>
stateVector[${odeVariable.getName()}_${indexPostfix}] = S_.${odeVariable.getName()};
<#assign index = index + 1>
</#list>

while ( t < step_ )
{
const int status = gsl_odeiv_evolve_apply( B_.e_,
B_.c_,
B_.s_,
Expand All @@ -34,8 +32,9 @@ double stateVector[${stateSize}];
&IntegrationStep_, // integration step size
stateVector ); // neuronal state
<#assign index = 0>
<#list body.getStateNonAliasSymbols() as stateVariable>
S_.${stateVariable.getName()} = stateVector[${stateVariable.getName()}_${indexPostfix}];

}
<#list body.variablesDefinedByODE() as odeVariable>
S_.${odeVariable.getName()} = stateVector[${odeVariable.getName()}_${indexPostfix}];
<#assign index = index + 1>
</#list>
}
</#list>
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.google.common.collect.Lists;
import de.monticore.symboltable.Scope;
import de.monticore.symboltable.ScopeSpanningSymbol;
import de.monticore.symboltable.Symbol;
import org.junit.Test;
import org.nest.base.ModelbasedTest;
import org.nest.nestml._ast.*;
Expand Down Expand Up @@ -55,12 +56,24 @@ public void testCreationOfSymtabAndResolvingOfSymbols() throws IOException {
Collection<TypeSymbol> nestmlTypes = modelScope.resolveLocally(NeuronSymbol.KIND);
assertEquals(2, nestmlTypes.size());

final Optional<TypeSymbol> neuronTypeOptional = modelScope.resolve(
final Optional<NeuronSymbol> neuronTypeOptional = modelScope.resolve(
"iaf_neuron",
NeuronSymbol.KIND);
assertTrue(neuronTypeOptional.isPresent());
final Optional<VariableSymbol> y0TVariable = neuronTypeOptional.get().getSpannedScope().resolve("y0", VariableSymbol.KIND);
final Optional<VariableSymbol> y1Varialbe = neuronTypeOptional.get().getSpannedScope().resolve("y1", VariableSymbol.KIND);
assertTrue(y0TVariable.isPresent());
assertTrue(y0TVariable.get().definedByODE());

final Optional<TypeSymbol> testComponentOptional = modelScope.resolve(
assertTrue(y1Varialbe.isPresent());
assertFalse(y1Varialbe.get().definedByODE());

// Checks that the derived variable is also resolvable
final Optional<VariableSymbol> Dy0Varialbe = neuronTypeOptional.get().getSpannedScope().resolve("__Dy0", VariableSymbol.KIND);
assertTrue(Dy0Varialbe.isPresent());
assertTrue(Dy0Varialbe.get().definedByODE());

final Optional<NeuronSymbol> testComponentOptional = modelScope.resolve(
"TestComponent",
NeuronSymbol.KIND);
assertTrue(testComponentOptional.isPresent());
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/org/nest/spl/parsing/SPLParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class SPLParserTest extends ModelbasedTest {

@Test
public void testParsableModels() throws IOException {
final List<Path> filenames = collectSPLModelFilenames(TEST_MODEL_PATH);
final List<Path> filenames = collectSPLModelFilenames(Paths.get("src/test/resources/org/nest/spl"));

filenames.forEach(this::parseAndCheck);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
/* * Copyright (c) 2015 RWTH Aachen. All rights reserved. * * http://www.se-rwth.de/ */package org.nest.spl.prettyprinter;import org.junit.Test;import org.nest.base.ModelbasedTest;import org.nest.spl._ast.ASTSPLFile;import org.nest.spl._parser.SPLParser;import org.nest.spl._symboltable.SPLLanguage;import java.io.IOException;import java.io.StringReader;import java.nio.file.Path;import java.nio.file.Paths;import java.util.List;import java.util.Optional;import static org.junit.Assert.assertTrue;import static org.nest.utils.FilesHelper.collectFiles;/** * Checks that the pretty printed result can be parsed again. * * @author plotnikov */public class SPLPrettyPrinterTest extends ModelbasedTest { private final SPLParser splFileParser = new SPLParser(); private final ExpressionsPrettyPrinter prettyPrinter = new ExpressionsPrettyPrinter(); private Optional<ASTSPLFile> parseStringAsSPLFile(final String fileAsString) throws IOException { return splFileParser.parse(new StringReader(fileAsString)); } @Test public void testThatPrettyPrinterProducesParsableOutput() throws IOException { final SPLPrettyPrinter splPrettyPrinter = new SPLPrettyPrinter(prettyPrinter); final Optional<ASTSPLFile> root = splFileParser.parse //("src/test/resources/org/nest/spl/parsing/modelContainingAllLanguageElements.simple"); ("src/test/resources/org/nest/spl/parsing/complexExpressions.simple"); assertTrue(root.isPresent()); root.get().accept(splPrettyPrinter); // starts prettyPrinter Optional<ASTSPLFile> prettyPrintedRoot = parseStringAsSPLFile(splPrettyPrinter.getResult()); assertTrue(prettyPrintedRoot.isPresent()); System.out.println(splPrettyPrinter.getResult()); } @Test public void testAllModelsForParser() throws IOException { parseAndCheckSPLModelsFromFolder("src/test/resources/org/nest/spl/parsing"); } @Test public void testAllModelsForCocos() throws IOException { parseAndCheckSPLModelsFromFolder("src/test/resources/org/nest/spl/_cocos"); } private void parseAndCheckSPLModelsFromFolder(final String folderPath) throws IOException { final List<Path> splFiles = collectFiles( Paths.get(folderPath), model -> model.endsWith(SPLLanguage.FILE_ENDING)); for (final Path splModelFile : splFiles) { System.out.println("Handles the model: " + splModelFile); final SPLPrettyPrinter splPrettyPrinter = new SPLPrettyPrinter(prettyPrinter); final Optional<ASTSPLFile> splModelRoot = splFileParser.parse(splModelFile.toString()); assertTrue("Cannot parse the model: " + splModelFile, splModelRoot.isPresent()); splModelRoot.get().accept(splPrettyPrinter); //System.out.println(splPrettyPrinter.getResult()); Optional<ASTSPLFile> prettyPrintedRoot = parseStringAsSPLFile(splPrettyPrinter.getResult()); assertTrue(prettyPrintedRoot.isPresent()); } }}
/* * Copyright (c) 2015 RWTH Aachen. All rights reserved. * * http://www.se-rwth.de/ */package org.nest.spl.prettyprinter;import org.junit.Test;import org.nest.base.ModelbasedTest;import org.nest.spl._ast.ASTSPLFile;import org.nest.spl._parser.SPLParser;import org.nest.spl._symboltable.SPLLanguage;import java.io.IOException;import java.io.StringReader;import java.nio.file.Path;import java.nio.file.Paths;import java.util.List;import java.util.Optional;import static org.junit.Assert.assertTrue;import static org.nest.utils.FilesHelper.collectFiles;/** * Checks that the pretty printed result can be parsed again. * * @author plotnikov */public class SPLPrettyPrinterTest extends ModelbasedTest { private final SPLParser splFileParser = new SPLParser(); private final ExpressionsPrettyPrinter prettyPrinter = new ExpressionsPrettyPrinter(); private Optional<ASTSPLFile> parseStringAsSPLFile(final String fileAsString) throws IOException { return splFileParser.parse(new StringReader(fileAsString)); } @Test public void testThatPrettyPrinterProducesParsableOutput() throws IOException { final SPLPrettyPrinter splPrettyPrinter = new SPLPrettyPrinter(prettyPrinter); final Optional<ASTSPLFile> root = splFileParser.parse //("src/test/resources/org/nest/spl/parsing/modelContainingAllLanguageElements.simple"); ("src/test/resources/org/nest/spl/parsing/complexExpressions.simple"); assertTrue(root.isPresent()); root.get().accept(splPrettyPrinter); // starts prettyPrinter Optional<ASTSPLFile> prettyPrintedRoot = parseStringAsSPLFile(splPrettyPrinter.getResult()); assertTrue(prettyPrintedRoot.isPresent()); System.out.println(splPrettyPrinter.getResult()); } @Test public void testAllModelsForParser() throws IOException { parseAndCheckSPLModelsFromFolder("src/test/resources/org/nest/spl"); } private void parseAndCheckSPLModelsFromFolder(final String folderPath) throws IOException { final List<Path> splFiles = collectFiles( Paths.get(folderPath), model -> model.endsWith(SPLLanguage.FILE_ENDING)); for (final Path splModelFile : splFiles) { System.out.println("Handles the model: " + splModelFile); final SPLPrettyPrinter splPrettyPrinter = new SPLPrettyPrinter(prettyPrinter); final Optional<ASTSPLFile> splModelRoot = splFileParser.parse(splModelFile.toString()); assertTrue("Cannot parse the model: " + splModelFile, splModelRoot.isPresent()); splModelRoot.get().accept(splPrettyPrinter); //System.out.println(splPrettyPrinter.getResult()); Optional<ASTSPLFile> prettyPrintedRoot = parseStringAsSPLFile(splPrettyPrinter.getResult()); assertTrue(prettyPrintedRoot.isPresent()); } }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ public void testTypeCalculation() throws IOException {

// n boolean = not true
assertType("n", declarations, getBooleanType());

// o1 real = true? 13:14
assertType("o1", declarations, getIntegerType());

// o2 string = true?"test1":"test"
assertType("o2", declarations, getStringType());
}

private void assertType(final String variableName, List<ASTDeclaration> declarations, final TypeSymbol expectedType) {
Expand Down Expand Up @@ -159,6 +165,11 @@ public void testNegativeExamples() throws IOException {
// n boolean = not 1
assertInvaidType("n", declarations);

//o1 real = 12? 13:14
assertInvaidType("o1", declarations);

//o2 real = true?13:"test"
assertInvaidType("o2", declarations);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ neuron iaf_neuron:
alias V_m mV = y3 + E_L
end

equations:
y0' = y0 + 1
y0'' = y0' + 1
end

parameter:
# Capacity of the membrane
C_m pF = 250
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ a real = ((( 1.0 | (-3+6%2) & ~(0x4fa) | 0x23 ^ 12) >> 2) << 2)
k integer = ~1.0
m real = 1 ** "a"
m1 boolean = "a" and k != 0.0
n boolean = not 1
n boolean = not 1
o1 real = 12? 13:14
o2 real = true?13:"test"
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ P11ex real = pow(1.0, 1.0) # TODO **,h / pow(E, (-h / tau_syn_ex))
tmp string = ("")
m boolean = true and l != 0.0
n boolean = not true
o1 real = true? 13:14
o2 string = true?"test1":"test"
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ RefractoryCounts integer = steps(t_ref)
# it is a pre-comment 1
print("" + ((( C_m | (-3+6%2) & ~(0x4fa) | 0x23) >> 2) << 2)) # it is a post comment 1
# it is a post commet 2
tmp real = (11 > 12)?13:14

0 comments on commit 7dc111e

Please sign in to comment.