/******************************************************************************* * Copyright 2014 Analog Devices, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ********************************************************************************/ package com.analog.lyric.dimple.test.model.core; import static org.junit.Assert.*; import java.util.Collection; import java.util.Iterator; import org.junit.Test; import com.analog.lyric.dimple.factorfunctions.Xor; import com.analog.lyric.dimple.model.core.FactorGraph; import com.analog.lyric.dimple.model.core.FactorGraphIterables; import com.analog.lyric.dimple.model.core.FactorGraphIterators; import com.analog.lyric.dimple.model.core.IFactorGraphChild; import com.analog.lyric.dimple.model.core.IFactorGraphChildIterator; import com.analog.lyric.dimple.model.core.IFactorGraphChildren; import com.analog.lyric.dimple.model.factors.Factor; import com.analog.lyric.dimple.model.variables.Bit; import com.analog.lyric.dimple.model.variables.Constant; import com.analog.lyric.dimple.model.variables.Variable; import com.analog.lyric.dimple.model.variables.VariableBlock; import com.analog.lyric.dimple.test.DimpleTestBase; /** * * @since 0.08 * @author Christopher Barber */ public class TestNestedIterators extends DimpleTestBase { @Test public void test() { FactorGraph fg = new FactorGraph("fg"); Variable v0a = bit("v0a"); Variable v0b = bit("v0b"); Variable v0c = bit("v0c"); fg.addVariables(v0a, v0b, v0c); Factor f0a = fg.addFactor(new Xor(), v0a, v0b); Factor f0b = fg.addFactor(new Xor(), v0b, v0c); Constant c0a = fg.addConstant(42); Constant c0b = fg.addConstant(Math.PI); assertSame(fg, c0a.getParentGraph()); VariableBlock b0a = fg.addVariableBlock(v0a,v0b); assertOrder(FactorGraphIterators.subgraphs(fg), fg); assertOrder(FactorGraphIterables.subgraphs(fg), fg); assertOrder(FactorGraphIterators.variables(fg), v0a, v0b, v0c); assertOrder(FactorGraphIterables.variables(fg), v0a, v0b, v0c); assertOrder(FactorGraphIterators.factors(fg), f0a, f0b); assertOrder(FactorGraphIterables.factors(fg), f0a, f0b); assertOrder(FactorGraphIterators.constants(fg), c0a, c0b); assertOrder(FactorGraphIterables.constants(fg), c0a, c0b); assertOrder(FactorGraphIterators.variableBlocks(fg), b0a); assertOrder(FactorGraphIterables.variableBlocks(fg), b0a); Variable v0d = bit("v0d"); FactorGraph fg1a = fg.addGraph(new FactorGraph(new Bit(), new Bit()), v0d, v0b); Variable v1a1 = bit("v1a1"); Variable v1a2 = bit("v1a2"); fg1a.addVariables(v1a1, v1a2); Factor f1a1 = fg1a.addFactor(new Xor(), v0b, v1a1); Factor f1a2 = fg1a.addFactor(new Xor(), v1a1, v1a2); Constant c1a1 = fg1a.addConstant(12); Constant c1a2 = fg1a.addConstant(0.0); VariableBlock b1a1 = fg1a.addVariableBlock(v1a1,v1a2); FactorGraph fg2a = fg1a.addGraph(new FactorGraph("fg2a")); FactorGraph fg2b = fg1a.addGraph(new FactorGraph(new Bit()), v0d); fg2b.setName("fg2b"); Variable v2b1 = bit("v2b1"); Variable v2b2 = bit("v2b2"); Factor f2b1 = fg2b.addFactor(new Xor(), v0d, v2b1); Factor f2b2 = fg2b.addFactor(new Xor(), v2b1, v2b2); Constant c2b1 = fg2b.addConstant(1); Constant c2b2 = fg2b.addConstant(2); FactorGraph fg3b = fg1a.addGraph(new FactorGraph("fg3b")); FactorGraph fg1b = fg.addGraph(new FactorGraph("fb1b")); assertOrder(FactorGraphIterators.subgraphs(fg), fg, fg1a, fg2a, fg2b, fg3b, fg1b); assertOrder(FactorGraphIterables.subgraphs(fg), fg, fg1a, fg2a, fg2b, fg3b, fg1b); assertOrder(FactorGraphIterators.subgraphsDownto(fg, 0), fg); assertOrder(FactorGraphIterables.subgraphsDownto(fg, 0), fg); assertOrder(FactorGraphIterators.subgraphsDownto(fg, 1), fg, fg1a, fg1b); assertOrder(FactorGraphIterables.subgraphsDownto(fg, 1), fg, fg1a, fg1b); assertOrder(FactorGraphIterators.subgraphs(fg1a), fg1a, fg2a, fg2b, fg3b); assertOrder(FactorGraphIterables.subgraphs(fg1a), fg1a, fg2a, fg2b, fg3b); assertOrder(FactorGraphIterators.constants(fg), c0a, c0b, c1a1, c1a2, c2b1, c2b2); assertOrder(FactorGraphIterables.constants(fg), c0a, c0b, c1a1, c1a2, c2b1, c2b2); assertOrder(FactorGraphIterators.constantsDownto(fg, 0), c0a, c0b); assertOrder(FactorGraphIterables.constantsDownto(fg, 0), c0a, c0b); assertOrder(FactorGraphIterators.constantsDownto(fg, 1), c0a, c0b, c1a1, c1a2); assertOrder(FactorGraphIterables.constantsDownto(fg, 1), c0a, c0b, c1a1, c1a2); assertOrder(FactorGraphIterators.constants(fg1a), c1a1, c1a2, c2b1, c2b2); assertOrder(FactorGraphIterables.constants(fg1a), c1a1, c1a2, c2b1, c2b2); assertOrder(FactorGraphIterators.factors(fg), f0a, f0b, f1a1, f1a2, f2b1, f2b2); assertOrder(FactorGraphIterables.factors(fg), f0a, f0b, f1a1, f1a2, f2b1, f2b2); assertOrder(FactorGraphIterators.factorsDownto(fg, 0), f0a, f0b); assertOrder(FactorGraphIterables.factorsDownto(fg, 0), f0a, f0b); assertOrder(FactorGraphIterators.factorsDownto(fg, 1), f0a, f0b, f1a1, f1a2); assertOrder(FactorGraphIterables.factorsDownto(fg, 1), f0a, f0b, f1a1, f1a2); assertOrder(FactorGraphIterators.factors(fg1a), f1a1, f1a2, f2b1, f2b2); assertOrder(FactorGraphIterables.factors(fg1a), f1a1, f1a2, f2b1, f2b2); assertOrder(FactorGraphIterators.variables(fg), v0a, v0b, v0c, v0d, v1a1, v1a2, v2b1, v2b2); assertOrder(FactorGraphIterables.variables(fg), v0a, v0b, v0c, v0d, v1a1, v1a2, v2b1, v2b2); assertOrder(FactorGraphIterators.variablesDownto(fg, 0), v0a, v0b, v0c, v0d); assertOrder(FactorGraphIterables.variablesDownto(fg, 0), v0a, v0b, v0c, v0d); assertOrder(FactorGraphIterators.variablesDownto(fg, 1), v0a, v0b, v0c, v0d, v1a1, v1a2); assertOrder(FactorGraphIterables.variablesDownto(fg, 1), v0a, v0b, v0c, v0d, v1a1, v1a2); assertOrder(FactorGraphIterators.variables(fg1a), v1a1, v1a2, v2b1, v2b2); assertOrder(FactorGraphIterables.variables(fg1a), v1a1, v1a2, v2b1, v2b2); assertOrder(FactorGraphIterators.variablesAndBoundary(fg1a), v0d, v0b, v1a1, v1a2, v2b1, v2b2); assertOrder(FactorGraphIterables.variablesAndBoundary(fg1a), v0d, v0b, v1a1, v1a2, v2b1, v2b2); assertOrder(FactorGraphIterators.boundary(fg)); assertOrder(FactorGraphIterators.boundary(fg)); assertOrder(FactorGraphIterators.boundary(fg1a), v0d, v0b); assertOrder(FactorGraphIterables.boundary(fg1a), v0d, v0b); assertOrder(FactorGraphIterators.boundary(fg2b), v0d); assertOrder(FactorGraphIterables.boundary(fg2b), v0d); assertOrder(FactorGraphIterators.variableBlocks(fg), b0a, b1a1); assertOrder(FactorGraphIterables.variableBlocks(fg), b0a, b1a1); assertOrder(FactorGraphIterators.variableBlocksDownto(fg, 0), b0a); assertOrder(FactorGraphIterables.variableBlocksDownto(fg, 0), b0a); assertOrder(FactorGraphIterators.variableBlocks(fg1a), b1a1); assertOrder(FactorGraphIterables.variableBlocks(fg1a), b1a1); for (FactorGraph subgraph : FactorGraphIterables.subgraphs(fg)) { assertSameOrder(subgraph.getOwnedConstants(), FactorGraphIterators.ownedConstants(subgraph)); assertSameOrder(subgraph.getOwnedFactors(), FactorGraphIterators.ownedFactors(subgraph)); assertSameOrder(subgraph.getOwnedGraphs(), FactorGraphIterators.ownedSubgraphs(subgraph)); assertSameOrder(subgraph.getOwnedVariables(), FactorGraphIterators.ownedVariables(subgraph)); assertSameOrder(subgraph.getOwnedVariableBlocks(), FactorGraphIterators.ownedVariableBlocks(subgraph)); } } private Bit bit(String name) { Bit bit = new Bit(); bit.setName(name); return bit; } private <T> void assertSameOrder(Collection<T> collection, Iterator<T> iterator) { Iterator<T> collectionIter = collection.iterator(); int size = 0; while (iterator.hasNext()) { assertTrue(collectionIter.hasNext()); assertSame(collectionIter.next(), iterator.next()); ++size; } assertEquals(size, collection.size()); } private void assertOrder(IFactorGraphChildren<FactorGraph> children, FactorGraph ...graphs) { assertEquals(graphs.length, children.size()); assertSame(graphs[0], children.root()); IFactorGraphChildIterator<FactorGraph> iterator = children.iterator(); assertSame(children.root(), iterator.root()); assertEquals(children.maxNestingDepth(), iterator.maxNestingDepth()); assertOrder(iterator, graphs); } private void assertOrder(IFactorGraphChildIterator<FactorGraph> iterator, FactorGraph ... graphs) { assertEquals(-1, iterator.lastDepth()); assertSame(graphs[0], iterator.root()); int i = 0; while (iterator.hasNext()) { FactorGraph fg = iterator.next(); assertNotNull(fg); assertSame(graphs[i++], fg); if (fg != iterator.root()) { int depth = fg.getDepthBelowAncestor(iterator.root()); assertEquals(depth + 1, iterator.lastDepth()); assertTrue(depth >= 0); assertTrue(depth < iterator.maxNestingDepth()); } else { assertEquals(0, iterator.lastDepth()); } } assertNull(iterator.next()); assertEquals(-1, iterator.lastDepth()); assertEquals(graphs.length, i); iterator.reset(); i = 0; while (true) { FactorGraph fg = iterator.next(); if (fg != null) { assertSame(graphs[i++], fg); } else { assert !iterator.hasNext(); break; } } assertEquals(-1, iterator.lastDepth()); } @SuppressWarnings("unchecked") private <T extends IFactorGraphChild> void assertOrder(IFactorGraphChildren<T> children, T ... expected) { assertEquals(expected.length, children.size()); IFactorGraphChildIterator<T> iterator = children.iterator(); assertSame(children.root(), iterator.root()); assertEquals(children.maxNestingDepth(), iterator.maxNestingDepth()); assertOrder(iterator, expected); } private <T extends IFactorGraphChild> void assertOrder(IFactorGraphChildIterator<T> iterator, @SuppressWarnings("unchecked") T ... children) { final FactorGraph root = iterator.root(); int i = 0; while (iterator.hasNext()) { T child = iterator.next(); assertNotNull(child); assertSame(children[i++], child); if (child != iterator.root()) { int depth = 0; for (FactorGraph parent = child.getParentGraph(); parent != null; parent = parent.getParentGraph()) { if (parent == root) { assertTrue(depth - 1 < iterator.maxNestingDepth()); break; } ++depth; } } } assertNull(iterator.next()); assertEquals(children.length, i); iterator.reset(); i = 0; while (true) { T node = iterator.next(); if (node != null) { assertSame(children[i++], node); } else { assert !iterator.hasNext(); break; } } } }