Skip to content

Commit

Permalink
Merge pull request #389 from kleis-technology/fix/evaluator
Browse files Browse the repository at this point in the history
  • Loading branch information
jedesroches authored Oct 24, 2023
2 parents 96b25d1 + adb3cca commit 14f2dcc
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,17 @@ class EvaluationTrace<Q> {
entryPoint = process
} else throw EvaluatorException("execution trace contains multiple entrypoint")
}
processes.add(process)
currentStage.add(process)
if (!processes.contains(process)) {
processes.add(process)
currentStage.add(process)
}
}

fun addSubstanceCharacterization(substanceCharacterization: SubstanceCharacterizationValue<Q>) {
substanceCharacterizations.add(substanceCharacterization)
currentStage.add(substanceCharacterization)
if (!substanceCharacterizations.contains(substanceCharacterization)) {
substanceCharacterizations.add(substanceCharacterization)
currentStage.add(substanceCharacterization)
}
}

fun commit() {
Expand All @@ -101,8 +105,11 @@ class EvaluationTrace<Q> {
process.products.forEach { exchange ->
updateDepthMap(exchange.product, currentDepth)
}
val processProducts = process.products.map { it.product }
process.inputs.forEach { exchange ->
updateDepthMap(exchange.product, currentDepth + 1)
if (!processProducts.contains(exchange.product)) { // avoid self loop
updateDepthMap(exchange.product, currentDepth + 1)
}
}
process.biosphere.forEach { exchange ->
updateDepthMap(exchange.substance, currentDepth + 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,19 +122,17 @@ class Learner<Q>(
Heap.VIRTUAL_ADDRESS -> start.find(address.portIndex)
?.let { port ->
val process = response.value
val selectedPortIndex = response.productInProcessIndex
val product = process.products[selectedPortIndex].product
val product = process.products[response.productInProcessIndex].product
knowledge[port] = product
}

else -> {
val process = response.value
val selectedPortIndex = response.productInProcessIndex
val product = process.products[selectedPortIndex].product
val product = process.products[response.productInProcessIndex].product
staging.find(address.connectionIndex)
?.let { existingConnection ->
if (existingConnection is EProcess<Q>) {
knowledge[existingConnection.inputs[selectedPortIndex].product] = product
knowledge[existingConnection.inputs[address.portIndex].product] = product
}
}
staging.modify(
Expand Down
59 changes: 59 additions & 0 deletions grammar/src/test/kotlin/ch/kleis/lcaac/grammar/EvaluatorTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,65 @@ import org.junit.jupiter.api.Test
import kotlin.test.assertEquals

class EvaluatorTest {
@Test
fun arena_shouldHandleKnowledgeCorrectly() {
// given
val file = lcaFile(
"""
process a_proc {
products {
1 kg a
}
inputs {
1 kg b from b_proc
1 l c from c_proc
}
}
process b_proc {
products {
1 kg b
}
impacts {
1 kg gwp
}
}
process c_proc {
products {
1 l c
}
inputs {
1kg b from b_proc
}
impacts {
1 kg gwp
}
}
""".trimIndent()
)
val loader = Loader(BasicOperations)
val symbolTable = loader.load(sequenceOf(file), listOf(LoaderOption.WITH_PRELUDE))
val spec = EProductSpec<BasicNumber>(
name = "a",
fromProcess = FromProcess("a_proc", MatchLabels(emptyMap())),
)
val evaluator = Evaluator(symbolTable, BasicOperations)

// when
val trace = evaluator.trace(setOf(spec))
val program = ContributionAnalysisProgram(trace.getSystemValue(), trace.getEntryPoint())
val analysis = program.run()

// then
val port = analysis.getObservablePorts().get("a from a_proc{}{}")
val indicator = analysis.getControllablePorts().get("gwp")
val expected = QuantityValue(BasicNumber(3.0), UnitValue(UnitSymbol.of("kg"), 1.0, Dimension.of("mass")))
val actual = analysis.getPortContribution(port, indicator)
assertEquals(expected, actual)
}


@Test
fun arena_with1HopLoop() {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,23 +646,28 @@ class SankeyGraphWindowBuilderTest : BasePlatformTestCase() {
GraphNode("H from pH{}{}", "H"),
GraphNode("my_emission", "my_emission")
).addLink(
GraphLink("F from pF{}{}", "H from pH{}{}", value = 1.5, "1.5 u"),
GraphLink("C from pC{}{}", "F from pF{}{}", value = 0.5, "0.5 u"),
GraphLink("A from pA{}{}", "B from pB{}{}", value = 3.0, "3 u"),
GraphLink("A from pA{}{}", "C from pC{}{}", value = 0.5, "0.5 u"),
GraphLink("D from pD{}{}", "F from pF{}{}", value = 1.0, "1.0 u"),
GraphLink("H from pH{}{}", "my_emission", value = 3.5, "3.5 u"),
GraphLink("B from pB{}{}", "D from pD{}{}", value = 1.0, "1 u"),
GraphLink("B from pB{}{}", "E from pE{}{}", value = 2.0, "2 u"),
GraphLink("E from pE{}{}", "G from pG{}{}", value = 4.0, "4 u"),
GraphLink("G from pG{}{}", "H from pH{}{}", value = 2.0, "2 u"),
GraphLink("F from pF{}{}", "H from pH{}{}", value = 1.5, "1.5 kg"),
GraphLink("C from pC{}{}", "F from pF{}{}", value = 0.5, "0.5 kg"),
GraphLink("A from pA{}{}", "B from pB{}{}", value = 3.0, "3 kg"),
GraphLink("A from pA{}{}", "C from pC{}{}", value = 0.5, "0.5 kg"),
GraphLink("D from pD{}{}", "F from pF{}{}", value = 1.0, "1 kg"),
GraphLink("H from pH{}{}", "my_emission", value = 3.5, "3.5 kg"),
GraphLink("B from pB{}{}", "D from pD{}{}", value = 1.0, "1 kg"),
GraphLink("B from pB{}{}", "E from pE{}{}", value = 2.0, "2 kg"),
GraphLink("E from pE{}{}", "G from pG{}{}", value = 4.0, "4 kg"),
GraphLink("G from pG{}{}", "H from pH{}{}", value = 2.0, "2 kg"),
)

assertEquals(expected.nodes.naturalSorted(), graph.nodes.naturalSorted())
expected.links.naturalSorted().zip(graph.links.naturalSorted()).forEach { (expected, actual) ->
expected.links.sortBySourceAndTarget().zip(graph.links.sortBySourceAndTarget()).forEach { (expected, actual) ->
assertEquals(expected.source, actual.source)
assertEquals(expected.target, actual.target)
assertEquals(expected.value, actual.value, 0.0001)
assertEquals(expected.name, actual.name)
}
}

private fun Set<GraphLink>.sortBySourceAndTarget(): List<GraphLink> {
return this.sortedBy { "${it.source}, ${it.target}" }
}
}
57 changes: 57 additions & 0 deletions plugin/src/test/kotlin/ch/kleis/lcaac/plugin/e2e/E2ETest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,63 @@ class E2ETest : BasePlatformTestCase() {
return "testdata"
}

@Test
fun test_shouldHandleKnowledgeCorrectly() {
// given
val pkgName = {}.javaClass.enclosingMethod.name
val vf = myFixture.createFile(
"$pkgName.lca", """
process a_proc {
products {
1 kg a
}
inputs {
1 kg b from b_proc
1 l c from c_proc
}
}
process b_proc {
products {
1 kg b
}
impacts {
1 kg gwp
}
}
process c_proc {
products {
1 l c
}
inputs {
1kg b from b_proc
}
impacts {
1 kg gwp
}
}
""".trimIndent()
)
val symbolTable = createFilesAndSymbols(vf)

// when
val template = symbolTable.getTemplate("a_proc")!!
val trace = Evaluator(symbolTable, ops).trace(template)
val system = trace.getSystemValue()
val assessment = ContributionAnalysisProgram(system, trace.getEntryPoint())
val result = assessment.run().getImpactFactors()
val output = result.observablePorts.get("a from a_proc{}{}")
val input = result.controllablePorts.get("gwp")
val cf = result.characterizationFactor(output, input)

// then
assertEquals(
QuantityValue(ops.pure(3.0), umap["kg"]!! / umap["kg"]!!),
cf,
)
}

@Test
fun test_patternMatching() {
// given
Expand Down

0 comments on commit 14f2dcc

Please sign in to comment.