From 7f2df1ba80aac7e1c5e99315bf5a8e32ad7456da Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Fri, 21 Jul 2023 02:18:06 +0200 Subject: feat: custom connected component RETE node --- .../viatra/StronglyConnectedComponentsTest.java | 217 +++++++++++++++++++++ .../viatra/WeaklyConnectedComponentsTest.java | 188 ++++++++++++++++++ 2 files changed, 405 insertions(+) create mode 100644 subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/StronglyConnectedComponentsTest.java create mode 100644 subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/WeaklyConnectedComponentsTest.java (limited to 'subprojects/store-query-viatra/src/test') diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/StronglyConnectedComponentsTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/StronglyConnectedComponentsTest.java new file mode 100644 index 00000000..05ea1bbb --- /dev/null +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/StronglyConnectedComponentsTest.java @@ -0,0 +1,217 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.store.query.viatra; + +import org.junit.jupiter.api.Test; +import tools.refinery.store.model.ModelStore; +import tools.refinery.store.query.ModelQueryAdapter; +import tools.refinery.store.query.dnf.Query; +import tools.refinery.store.query.literal.Connectivity; +import tools.refinery.store.query.literal.RepresentativeElectionLiteral; +import tools.refinery.store.query.view.AnySymbolView; +import tools.refinery.store.query.view.KeyOnlyView; +import tools.refinery.store.representation.Symbol; +import tools.refinery.store.tuple.Tuple; + +import java.util.List; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static tools.refinery.store.query.viatra.tests.QueryAssertions.assertResults; + +class StronglyConnectedComponentsTest { + private static final Symbol friend = Symbol.of("friend", 2); + private static final AnySymbolView friendView = new KeyOnlyView<>(friend); + + @Test + void symbolViewTest() { + var query = Query.of("SymbolViewRepresentative", (builder, p1, p2) -> builder + .clause(v1 -> List.of( + new RepresentativeElectionLiteral(Connectivity.STRONG, friendView, p1, v1), + new RepresentativeElectionLiteral(Connectivity.STRONG, friendView, p2, v1) + ))); + + var store = ModelStore.builder() + .symbols(friend) + .with(ViatraModelQueryAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var friendInterpretation = model.getInterpretation(friend); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var resultSet = queryEngine.getResultSet(query); + + friendInterpretation.put(Tuple.of(0, 1), true); + friendInterpretation.put(Tuple.of(1, 0), true); + friendInterpretation.put(Tuple.of(1, 2), true); + queryEngine.flushChanges(); + + assertResults(Map.of( + Tuple.of(0, 0), true, + Tuple.of(0, 1), true, + Tuple.of(1, 0), true, + Tuple.of(1, 1), true, + Tuple.of(2, 2), true + ), resultSet); + } + + @Test + void symbolViewInsertTest() { + var query = Query.of("SymbolViewRepresentative", (builder, p1, p2) -> builder + .clause(v1 -> List.of( + new RepresentativeElectionLiteral(Connectivity.STRONG, friendView, p1, v1), + new RepresentativeElectionLiteral(Connectivity.STRONG, friendView, p2, v1) + ))); + + var store = ModelStore.builder() + .symbols(friend) + .with(ViatraModelQueryAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var friendInterpretation = model.getInterpretation(friend); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var resultSet = queryEngine.getResultSet(query); + + friendInterpretation.put(Tuple.of(0, 1), true); + friendInterpretation.put(Tuple.of(1, 0), true); + friendInterpretation.put(Tuple.of(1, 2), true); + queryEngine.flushChanges(); + + friendInterpretation.put(Tuple.of(2, 0), true); + friendInterpretation.put(Tuple.of(0, 3), true); + queryEngine.flushChanges(); + + assertResults(Map.of( + Tuple.of(0, 0), true, + Tuple.of(0, 1), true, + Tuple.of(0, 2), true, + Tuple.of(1, 1), true, + Tuple.of(1, 0), true, + Tuple.of(1, 2), true, + Tuple.of(2, 0), true, + Tuple.of(2, 1), true, + Tuple.of(2, 2), true, + Tuple.of(3, 3), true + ), resultSet); + } + + @Test + void symbolViewDeleteTest() { + var query = Query.of("SymbolViewRepresentative", (builder, p1, p2) -> builder + .clause(v1 -> List.of( + new RepresentativeElectionLiteral(Connectivity.STRONG, friendView, p1, v1), + new RepresentativeElectionLiteral(Connectivity.STRONG, friendView, p2, v1) + ))); + + var store = ModelStore.builder() + .symbols(friend) + .with(ViatraModelQueryAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var friendInterpretation = model.getInterpretation(friend); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var resultSet = queryEngine.getResultSet(query); + + friendInterpretation.put(Tuple.of(0, 1), true); + friendInterpretation.put(Tuple.of(1, 0), true); + friendInterpretation.put(Tuple.of(1, 2), true); + queryEngine.flushChanges(); + + friendInterpretation.put(Tuple.of(1, 0), false); + friendInterpretation.put(Tuple.of(1, 2), false); + queryEngine.flushChanges(); + + assertResults(Map.of( + Tuple.of(0, 0), true, + Tuple.of(1, 1), true + ), resultSet); + } + + @Test + void diagonalSymbolViewTest() { + var person = Symbol.of("Person", 1); + var personView = new KeyOnlyView<>(person); + + var query = Query.of("SymbolViewRepresentative", (builder, p1) -> builder + .clause( + personView.call(p1), + new RepresentativeElectionLiteral(Connectivity.STRONG, friendView, p1, p1) + )); + + var store = ModelStore.builder() + .symbols(person, friend) + .with(ViatraModelQueryAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var personInterpretation = model.getInterpretation(person); + var friendInterpretation = model.getInterpretation(friend); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var resultSet = queryEngine.getResultSet(query); + + personInterpretation.put(Tuple.of(0), true); + personInterpretation.put(Tuple.of(1), true); + personInterpretation.put(Tuple.of(2), true); + + friendInterpretation.put(Tuple.of(0, 1), true); + friendInterpretation.put(Tuple.of(1, 0), true); + friendInterpretation.put(Tuple.of(1, 2), true); + queryEngine.flushChanges(); + + assertThat(resultSet.size(), is(2)); + assertThat(resultSet.get(Tuple.of(2)), is(true)); + } + + @Test + void diagonalDnfTest() { + var person = Symbol.of("Person", 1); + var personView = new KeyOnlyView<>(person); + + var subQuery = Query.of("SubQuery", (builder, p1, p2) -> builder + .clause( + personView.call(p1), + personView.call(p2), + friendView.call(p1, p2) + )) + .getDnf(); + var query = Query.of("SymbolViewRepresentative", (builder, p1) -> builder + .clause( + personView.call(p1), + new RepresentativeElectionLiteral(Connectivity.STRONG, subQuery, p1, p1) + )); + + var store = ModelStore.builder() + .symbols(person, friend) + .with(ViatraModelQueryAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var personInterpretation = model.getInterpretation(person); + var friendInterpretation = model.getInterpretation(friend); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var resultSet = queryEngine.getResultSet(query); + + personInterpretation.put(Tuple.of(0), true); + personInterpretation.put(Tuple.of(1), true); + personInterpretation.put(Tuple.of(2), true); + + friendInterpretation.put(Tuple.of(0, 1), true); + friendInterpretation.put(Tuple.of(1, 0), true); + friendInterpretation.put(Tuple.of(1, 2), true); + queryEngine.flushChanges(); + + assertThat(resultSet.size(), is(2)); + assertThat(resultSet.get(Tuple.of(2)), is(true)); + } +} diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/WeaklyConnectedComponentsTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/WeaklyConnectedComponentsTest.java new file mode 100644 index 00000000..613d4284 --- /dev/null +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/WeaklyConnectedComponentsTest.java @@ -0,0 +1,188 @@ +/* + * SPDX-FileCopyrightText: 2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ +package tools.refinery.store.query.viatra; + +import org.junit.jupiter.api.Test; +import tools.refinery.store.model.ModelStore; +import tools.refinery.store.query.ModelQueryAdapter; +import tools.refinery.store.query.dnf.Query; +import tools.refinery.store.query.literal.Connectivity; +import tools.refinery.store.query.literal.RepresentativeElectionLiteral; +import tools.refinery.store.query.view.AnySymbolView; +import tools.refinery.store.query.view.KeyOnlyView; +import tools.refinery.store.representation.Symbol; +import tools.refinery.store.tuple.Tuple; + +import java.util.List; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static tools.refinery.store.query.viatra.tests.QueryAssertions.assertResults; + +class WeaklyConnectedComponentsTest { + private static final Symbol friend = Symbol.of("friend", 2); + private static final AnySymbolView friendView = new KeyOnlyView<>(friend); + + @Test + void symbolViewTest() { + var query = Query.of("SymbolViewRepresentative", (builder, p1, p2) -> builder + .clause(v1 -> List.of( + new RepresentativeElectionLiteral(Connectivity.WEAK, friendView, p1, v1), + new RepresentativeElectionLiteral(Connectivity.WEAK, friendView, p2, v1) + ))); + + var store = ModelStore.builder() + .symbols(friend) + .with(ViatraModelQueryAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var friendInterpretation = model.getInterpretation(friend); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var resultSet = queryEngine.getResultSet(query); + + friendInterpretation.put(Tuple.of(0, 1), true); + friendInterpretation.put(Tuple.of(1, 0), true); + friendInterpretation.put(Tuple.of(2, 3), true); + queryEngine.flushChanges(); + + assertResults(Map.of( + Tuple.of(0, 0), true, + Tuple.of(0, 1), true, + Tuple.of(1, 0), true, + Tuple.of(1, 1), true, + Tuple.of(2, 2), true, + Tuple.of(2, 3), true, + Tuple.of(3, 2), true, + Tuple.of(3, 3), true + ), resultSet); + } + + @Test + void symbolViewUpdateTest() { + var query = Query.of("SymbolViewRepresentative", (builder, p1, p2) -> builder + .clause(v1 -> List.of( + new RepresentativeElectionLiteral(Connectivity.WEAK, friendView, p1, v1), + new RepresentativeElectionLiteral(Connectivity.WEAK, friendView, p2, v1) + ))); + + var store = ModelStore.builder() + .symbols(friend) + .with(ViatraModelQueryAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var friendInterpretation = model.getInterpretation(friend); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var resultSet = queryEngine.getResultSet(query); + + friendInterpretation.put(Tuple.of(0, 1), true); + friendInterpretation.put(Tuple.of(1, 0), true); + friendInterpretation.put(Tuple.of(2, 3), true); + queryEngine.flushChanges(); + + friendInterpretation.put(Tuple.of(2, 3), false); + friendInterpretation.put(Tuple.of(1, 0), false); + friendInterpretation.put(Tuple.of(1, 2), true); + queryEngine.flushChanges(); + + assertResults(Map.of( + Tuple.of(0, 0), true, + Tuple.of(0, 1), true, + Tuple.of(0, 2), true, + Tuple.of(1, 0), true, + Tuple.of(1, 1), true, + Tuple.of(1, 2), true, + Tuple.of(2, 0), true, + Tuple.of(2, 1), true, + Tuple.of(2, 2), true + ), resultSet); + } + + @Test + void diagonalSymbolViewTest() { + var person = Symbol.of("Person", 1); + var personView = new KeyOnlyView<>(person); + + var query = Query.of("SymbolViewRepresentative", (builder, p1) -> builder + .clause( + personView.call(p1), + new RepresentativeElectionLiteral(Connectivity.WEAK, friendView, p1, p1) + )); + + var store = ModelStore.builder() + .symbols(person, friend) + .with(ViatraModelQueryAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var personInterpretation = model.getInterpretation(person); + var friendInterpretation = model.getInterpretation(friend); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var resultSet = queryEngine.getResultSet(query); + + personInterpretation.put(Tuple.of(0), true); + personInterpretation.put(Tuple.of(1), true); + personInterpretation.put(Tuple.of(2), true); + personInterpretation.put(Tuple.of(3), true); + + friendInterpretation.put(Tuple.of(0, 1), true); + friendInterpretation.put(Tuple.of(1, 0), true); + friendInterpretation.put(Tuple.of(2, 3), true); + queryEngine.flushChanges(); + + assertThat(resultSet.size(), is(2)); + assertThat(resultSet.get(Tuple.of(2)), is(true)); + } + + @Test + void diagonalDnfTest() { + var person = Symbol.of("Person", 1); + var personView = new KeyOnlyView<>(person); + + var subQuery = Query.of("SubQuery", (builder, p1, p2) -> builder + .clause( + personView.call(p1), + personView.call(p2), + friendView.call(p1, p2) + )) + .getDnf(); + var query = Query.of("SymbolViewRepresentative", (builder, p1) -> builder + .clause( + personView.call(p1), + new RepresentativeElectionLiteral(Connectivity.WEAK, subQuery, p1, p1) + )); + + var store = ModelStore.builder() + .symbols(person, friend) + .with(ViatraModelQueryAdapter.builder() + .queries(query)) + .build(); + + var model = store.createEmptyModel(); + var personInterpretation = model.getInterpretation(person); + var friendInterpretation = model.getInterpretation(friend); + var queryEngine = model.getAdapter(ModelQueryAdapter.class); + var resultSet = queryEngine.getResultSet(query); + + personInterpretation.put(Tuple.of(0), true); + personInterpretation.put(Tuple.of(1), true); + personInterpretation.put(Tuple.of(2), true); + personInterpretation.put(Tuple.of(3), true); + + friendInterpretation.put(Tuple.of(0, 1), true); + friendInterpretation.put(Tuple.of(1, 0), true); + friendInterpretation.put(Tuple.of(2, 3), true); + queryEngine.flushChanges(); + + assertThat(resultSet.size(), is(2)); + assertThat(resultSet.get(Tuple.of(2)), is(true)); + } +} -- cgit v1.2.3-70-g09d2