/*
* SPDX-FileCopyrightText: 2023 The Refinery Authors
*
* SPDX-License-Identifier: EPL-2.0
*/
package tools.refinery.store.query.interpreter;
import org.junit.jupiter.api.Test;
import tools.refinery.logic.dnf.Query;
import tools.refinery.logic.literal.Connectivity;
import tools.refinery.logic.literal.RepresentativeElectionLiteral;
import tools.refinery.store.model.ModelStore;
import tools.refinery.store.query.ModelQueryAdapter;
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.interpreter.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(QueryInterpreterAdapter.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(QueryInterpreterAdapter.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(QueryInterpreterAdapter.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(QueryInterpreterAdapter.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));
}
}