From aac386f0d8c4e4585026b11bfeca20f378f7f261 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Mon, 26 Sep 2022 00:39:23 +0200 Subject: refactor: move viatra into a separate subproject --- .../store/query/viatra/tests/QueryTest.java | 432 +++++++++++++++++++++ .../query/viatra/tests/QueryTransactionTest.java | 56 +++ 2 files changed, 488 insertions(+) create mode 100644 subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java create mode 100644 subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java (limited to 'subprojects/store-query-viatra/src/test') diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java new file mode 100644 index 00000000..4307ab6b --- /dev/null +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java @@ -0,0 +1,432 @@ +package tools.refinery.store.query.viatra.tests; + +import org.junit.jupiter.api.Test; +import tools.refinery.store.model.Tuple; +import tools.refinery.store.model.representation.Relation; +import tools.refinery.store.model.representation.TruthValue; +import tools.refinery.store.query.QueryableModel; +import tools.refinery.store.query.QueryableModelStore; +import tools.refinery.store.query.building.*; +import tools.refinery.store.query.viatra.ViatraQueryableModelStore; +import tools.refinery.store.query.view.FilteredRelationView; +import tools.refinery.store.query.view.KeyOnlyRelationView; +import tools.refinery.store.query.view.RelationView; + +import java.util.*; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class QueryTest { + @Test + void typeConstraintTest() { + Relation person = new Relation<>("Person", 1, false); + Relation asset = new Relation<>("Asset", 1, false); + RelationView personView = new KeyOnlyRelationView(person); + + List parameters = List.of(new Variable("p1")); + RelationAtom personRelationAtom = new RelationAtom(personView, parameters); + DNFAnd clause = new DNFAnd(Collections.emptySet(), List.of(personRelationAtom)); + DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, List.of(clause)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, asset), Set.of(personView), + Set.of(predicate)); + QueryableModel model = store.createModel(); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(asset, Tuple.of(1), true); + model.put(asset, Tuple.of(2), true); + + model.flushChanges(); + assertEquals(2, model.countResults(predicate)); + compareMatchSets(model.allResults(predicate), Set.of(List.of(Tuple.of(0)), List.of(Tuple.of(1)))); + } + + @Test + void relationConstraintTest() { + Relation person = new Relation("Person", 1, false); + Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); + RelationView personView = new KeyOnlyRelationView(person); + RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); + + Variable p1 = new Variable("p1"); + Variable p2 = new Variable("p2"); + List parameters = Arrays.asList(p1, p2); + + RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); + RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); + RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); + DNFAnd clause = new DNFAnd(Collections.emptySet(), + Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); + DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), + Set.of(personView, friendMustView), Set.of(predicate)); + QueryableModel model = store.createModel(); + + assertEquals(0, model.countResults(predicate)); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(person, Tuple.of(2), true); + model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); + model.put(friend, Tuple.of(1, 0), TruthValue.TRUE); + model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); + + assertEquals(0, model.countResults(predicate)); + + model.flushChanges(); + assertEquals(3, model.countResults(predicate)); + compareMatchSets(model.allResults(predicate), Set.of(List.of(Tuple.of(0), Tuple.of(1)), + List.of(Tuple.of(1), Tuple.of(0)), List.of(Tuple.of(1), Tuple.of(2)))); + } + + @Test + void andTest() { + Relation person = new Relation("Person", 1, false); + Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); + RelationView personView = new KeyOnlyRelationView(person); + RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); + + Variable p1 = new Variable("p1"); + Variable p2 = new Variable("p2"); + List parameters = Arrays.asList(p1, p2); + + RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); + RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); + RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); + RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p1)); + DNFAnd clause = new DNFAnd(Collections.emptySet(), + Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1, friendRelationAtom2)); + DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), + Set.of(personView, friendMustView), Set.of(predicate)); + QueryableModel model = store.createModel(); + + assertEquals(0, model.countResults(predicate)); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(person, Tuple.of(2), true); + + model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); + model.put(friend, Tuple.of(0, 2), TruthValue.TRUE); + + model.flushChanges(); + assertEquals(0, model.countResults(predicate)); + + model.put(friend, Tuple.of(1, 0), TruthValue.TRUE); + model.flushChanges(); + assertEquals(2, model.countResults(predicate)); + compareMatchSets(model.allResults(predicate), + Set.of(List.of(Tuple.of(0), Tuple.of(1)), List.of(Tuple.of(1), Tuple.of(0)))); + + model.put(friend, Tuple.of(2, 0), TruthValue.TRUE); + model.flushChanges(); + assertEquals(4, model.countResults(predicate)); + compareMatchSets(model.allResults(predicate), + Set.of(List.of(Tuple.of(0), Tuple.of(1)), List.of(Tuple.of(1), Tuple.of(0)), + List.of(Tuple.of(0), Tuple.of(2)), List.of(Tuple.of(2), Tuple.of(0)))); + } + + @Test + void existTest() { + Relation person = new Relation("Person", 1, false); + Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); + RelationView personView = new KeyOnlyRelationView(person); + RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); + + Variable p1 = new Variable("p1"); + Variable p2 = new Variable("p2"); + List parameters = List.of(p1); + + RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); + RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); + RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); + DNFAnd clause = new DNFAnd(Set.of(p2), + Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); + DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), + Set.of(personView, friendMustView), Set.of(predicate)); + QueryableModel model = store.createModel(); + + assertEquals(0, model.countResults(predicate)); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(person, Tuple.of(2), true); + model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); + model.put(friend, Tuple.of(1, 0), TruthValue.TRUE); + model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); + + assertEquals(0, model.countResults(predicate)); + + model.flushChanges(); + assertEquals(2, model.countResults(predicate)); + compareMatchSets(model.allResults(predicate), Set.of(List.of(Tuple.of(0)), List.of(Tuple.of(1)))); + } + + @Test + void orTest() { + Relation person = new Relation<>("Person", 1, false); + Relation animal = new Relation<>("Animal", 1, false); + Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); + RelationView personView = new KeyOnlyRelationView(person); + RelationView animalView = new KeyOnlyRelationView(animal); + RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); + + Variable p1 = new Variable("p1"); + Variable p2 = new Variable("p2"); + List parameters = Arrays.asList(p1, p2); + + // Person-Person friendship + RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); + RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); + RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); + DNFAnd clause1 = new DNFAnd(Collections.emptySet(), + Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1)); + + // Animal-Animal friendship + RelationAtom animalRelationAtom1 = new RelationAtom(animalView, List.of(p1)); + RelationAtom animalRelationAtom2 = new RelationAtom(animalView, List.of(p2)); + RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); + DNFAnd clause2 = new DNFAnd(Collections.emptySet(), + Arrays.asList(animalRelationAtom1, animalRelationAtom2, friendRelationAtom2)); + + // No inter-species friendship + + DNFPredicate predicate = new DNFPredicate("Or", parameters, Arrays.asList(clause1, clause2)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, animal, friend), + Set.of(personView, animalView, friendMustView), Set.of(predicate)); + QueryableModel model = store.createModel(); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(animal, Tuple.of(2), true); + model.put(animal, Tuple.of(3), true); + model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); + model.put(friend, Tuple.of(0, 2), TruthValue.TRUE); + model.put(friend, Tuple.of(2, 3), TruthValue.TRUE); + model.put(friend, Tuple.of(3, 0), TruthValue.TRUE); + + model.flushChanges(); + assertEquals(2, model.countResults(predicate)); + compareMatchSets(model.allResults(predicate), + Set.of(List.of(Tuple.of(0), Tuple.of(1)), List.of(Tuple.of(2), Tuple.of(3)))); + } + + @Test + void equalityTest() { + Relation person = new Relation("Person", 1, false); + RelationView personView = new KeyOnlyRelationView(person); + + Variable p1 = new Variable("p1"); + Variable p2 = new Variable("p2"); + List parameters = Arrays.asList(p1, p2); + + RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); + RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); + EquivalenceAtom equivalenceAtom = new EquivalenceAtom(true, p1, p2); + DNFAnd clause = new DNFAnd(Collections.emptySet(), + Arrays.asList(personRelationAtom1, personRelationAtom2, equivalenceAtom)); + DNFPredicate predicate = new DNFPredicate("Equality", parameters, List.of(clause)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person), Set.of(personView), Set.of(predicate)); + QueryableModel model = store.createModel(); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(person, Tuple.of(2), true); + + model.flushChanges(); + assertEquals(3, model.countResults(predicate)); + compareMatchSets(model.allResults(predicate), Set.of(List.of(Tuple.of(0), Tuple.of(0)), + List.of(Tuple.of(1), Tuple.of(1)), List.of(Tuple.of(2), Tuple.of(2)))); + } + + @Test + void inequalityTest() { + Relation person = new Relation("Person", 1, false); + Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); + RelationView personView = new KeyOnlyRelationView(person); + RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); + + Variable p1 = new Variable("p1"); + Variable p2 = new Variable("p2"); + Variable p3 = new Variable("p3"); + List parameters = Arrays.asList(p1, p2, p3); + + RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); + RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); + RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p3)); + RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p3)); + EquivalenceAtom inequivalenceAtom = new EquivalenceAtom(false, p1, p2); + DNFAnd clause = new DNFAnd(Collections.emptySet(), Arrays.asList(personRelationAtom1, personRelationAtom2, + friendRelationAtom1, friendRelationAtom2, inequivalenceAtom)); + DNFPredicate predicate = new DNFPredicate("Inequality", parameters, List.of(clause)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), + Set.of(personView, friendMustView), Set.of(predicate)); + QueryableModel model = store.createModel(); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(person, Tuple.of(2), true); + model.put(friend, Tuple.of(0, 2), TruthValue.TRUE); + model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); + + model.flushChanges(); + assertEquals(2, model.countResults(predicate)); + compareMatchSets(model.allResults(predicate), + Set.of(List.of(Tuple.of(0), Tuple.of(1), Tuple.of(2)), List.of(Tuple.of(1), Tuple.of(0), Tuple.of(2)))); + } + + @Test + void patternCallTest() { + Relation person = new Relation("Person", 1, false); + Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); + RelationView personView = new KeyOnlyRelationView(person); + RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); + + Variable p1 = new Variable("p1"); + Variable p2 = new Variable("p2"); + List parameters = Arrays.asList(p1, p2); + + RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); + RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); + RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); + DNFAnd clause = new DNFAnd(Collections.emptySet(), + Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); + DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); + + Variable p3 = new Variable("p3"); + Variable p4 = new Variable("p4"); + List substitution = Arrays.asList(p3, p4); + RelationAtom personRelationAtom3 = new RelationAtom(personView, List.of(p3)); + RelationAtom personRelationAtom4 = new RelationAtom(personView, List.of(p4)); + PredicateAtom friendPredicateAtom = new PredicateAtom(true, false, friendPredicate, substitution); + DNFAnd patternCallClause = new DNFAnd(Collections.emptySet(), + Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); + DNFPredicate predicate = new DNFPredicate("PatternCall", substitution, List.of(patternCallClause)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), + Set.of(personView, friendMustView), Set.of(friendPredicate, predicate)); + QueryableModel model = store.createModel(); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(person, Tuple.of(2), true); + model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); + model.put(friend, Tuple.of(1, 0), TruthValue.TRUE); + model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); + + model.flushChanges(); + + assertEquals(3, model.countResults(friendPredicate)); + } + + @Test + void negativePatternCallTest() { + Relation person = new Relation("Person", 1, false); + Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); + RelationView personView = new KeyOnlyRelationView(person); + RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); + + Variable p1 = new Variable("p1"); + Variable p2 = new Variable("p2"); + List parameters = Arrays.asList(p1, p2); + + RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); + RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); + RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); + DNFAnd clause = new DNFAnd(Collections.emptySet(), + Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); + DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); + + Variable p3 = new Variable("p3"); + Variable p4 = new Variable("p4"); + List substitution = Arrays.asList(p3, p4); + RelationAtom personRelationAtom3 = new RelationAtom(personView, List.of(p3)); + RelationAtom personRelationAtom4 = new RelationAtom(personView, List.of(p4)); + PredicateAtom friendPredicateAtom = new PredicateAtom(false, false, friendPredicate, substitution); + DNFAnd negativePatternCallClause = new DNFAnd(Collections.emptySet(), + Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); + DNFPredicate predicate = new DNFPredicate("NegativePatternCall", substitution, + List.of(negativePatternCallClause)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), + Set.of(personView, friendMustView), Set.of(friendPredicate, predicate)); + QueryableModel model = store.createModel(); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(person, Tuple.of(2), true); + model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); + model.put(friend, Tuple.of(1, 0), TruthValue.TRUE); + model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); + + model.flushChanges(); + assertEquals(6, model.countResults(predicate)); + } + + @Test + void transitivePatternCallTest() { + Relation person = new Relation("Person", 1, false); + Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); + RelationView personView = new KeyOnlyRelationView(person); + RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); + + Variable p1 = new Variable("p1"); + Variable p2 = new Variable("p2"); + List parameters = Arrays.asList(p1, p2); + + RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); + RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); + RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); + DNFAnd clause = new DNFAnd(Collections.emptySet(), + Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); + DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); + + Variable p3 = new Variable("p3"); + Variable p4 = new Variable("p4"); + List substitution = Arrays.asList(p3, p4); + RelationAtom personRelationAtom3 = new RelationAtom(personView, List.of(p3)); + RelationAtom personRelationAtom4 = new RelationAtom(personView, List.of(p4)); + PredicateAtom friendPredicateAtom = new PredicateAtom(true, true, friendPredicate, substitution); + DNFAnd patternCallClause = new DNFAnd(Collections.emptySet(), + Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); + DNFPredicate predicate = new DNFPredicate("TransitivePatternCall", substitution, + List.of(patternCallClause)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), + Set.of(personView, friendMustView), Set.of(friendPredicate, predicate)); + QueryableModel model = store.createModel(); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(person, Tuple.of(2), true); + model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); + model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); + + model.flushChanges(); + assertEquals(3, model.countResults(predicate)); + } + static void compareMatchSets(Stream matchSet, Set> expected) { + Set> translatedMatchSet = new HashSet<>(); + var iterator = matchSet.iterator(); + while (iterator.hasNext()) { + var element = iterator.next(); + List elementToTranslatedMatchSet = new ArrayList<>(); + for (Object o : element) { + elementToTranslatedMatchSet.add((Tuple) o); + } + translatedMatchSet.add(elementToTranslatedMatchSet); + } + + assertEquals(expected, translatedMatchSet); + } +} diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java new file mode 100644 index 00000000..613d0074 --- /dev/null +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java @@ -0,0 +1,56 @@ +package tools.refinery.store.query.viatra.tests; + +import org.junit.jupiter.api.Test; +import tools.refinery.store.model.Tuple; +import tools.refinery.store.model.representation.Relation; +import tools.refinery.store.query.QueryableModel; +import tools.refinery.store.query.QueryableModelStore; +import tools.refinery.store.query.building.DNFAnd; +import tools.refinery.store.query.building.DNFPredicate; +import tools.refinery.store.query.building.RelationAtom; +import tools.refinery.store.query.building.Variable; +import tools.refinery.store.query.viatra.ViatraQueryableModelStore; +import tools.refinery.store.query.view.KeyOnlyRelationView; +import tools.refinery.store.query.view.RelationView; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class QueryTransactionTest { + @Test + void flushTest() { + Relation person = new Relation<>("Person", 1, false); + Relation asset = new Relation<>("Asset", 1, false); + RelationView personView = new KeyOnlyRelationView(person); + + List parameters = List.of(new Variable("p1")); + RelationAtom personRelationAtom = new RelationAtom(personView, parameters); + DNFAnd clause = new DNFAnd(Collections.emptySet(), List.of(personRelationAtom)); + DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, List.of(clause)); + + QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, asset), Set.of(personView), + Set.of(predicate)); + QueryableModel model = store.createModel(); + + assertEquals(0, model.countResults(predicate)); + + model.put(person, Tuple.of(0), true); + model.put(person, Tuple.of(1), true); + model.put(asset, Tuple.of(1), true); + model.put(asset, Tuple.of(2), true); + + assertEquals(0, model.countResults(predicate)); + + model.flushChanges(); + assertEquals(2, model.countResults(predicate)); + + model.put(person, Tuple.of(4), true); + assertEquals(2, model.countResults(predicate)); + + model.flushChanges(); + assertEquals(3, model.countResults(predicate)); + } +} -- cgit v1.2.3-70-g09d2