/*******************************************************************************
* Copyright 2015 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.solvers.core;
import static com.analog.lyric.util.test.ExceptionTester.*;
import static java.util.Objects.*;
import static org.junit.Assert.*;
import java.util.LinkedHashSet;
import java.util.Set;
import org.junit.Test;
import com.analog.lyric.dimple.model.core.FactorGraph;
import com.analog.lyric.dimple.model.core.FactorGraphIterables;
import com.analog.lyric.dimple.model.factors.Factor;
import com.analog.lyric.dimple.model.variables.Bit;
import com.analog.lyric.dimple.model.variables.Discrete;
import com.analog.lyric.dimple.model.variables.Variable;
import com.analog.lyric.dimple.solvers.core.SFactorGraphBase;
import com.analog.lyric.dimple.solvers.interfaces.ISolverFactor;
import com.analog.lyric.dimple.solvers.interfaces.ISolverFactorGraph;
import com.analog.lyric.dimple.solvers.interfaces.ISolverVariable;
import com.analog.lyric.dimple.solvers.interfaces.SolverNodeMapping;
import com.analog.lyric.dimple.test.DimpleTestBase;
import com.analog.lyric.dimple.test.dummySolver.DummyFactorGraph;
import com.analog.lyric.dimple.test.dummySolver.DummySolver;
import com.analog.lyric.util.test.Helpers;
import com.google.common.collect.Iterables;
/**
* Unit tests for {@link SFactorGraphBase} class.
*/
public class TestSFactorGraphBase extends DimpleTestBase
{
@Test
public void test()
{
test(new FactorGraph());
test(Helpers.MakeSimpleGraph("simple"));
test(Helpers.MakeSimpleThreeLevelGraph());
}
private void test(FactorGraph fg)
{
DummyFactorGraph sfg = requireNonNull(fg.setSolverFactory(new DummySolver()));
assertInvariants(sfg);
}
private void assertInvariants(SFactorGraphBase<?,?,?,?> state)
{
final FactorGraph root = state.getModelObject();
assertSame(root, state.getModelGraph());
SolverNodeMapping solvers = state.getSolverMapping();
for (Variable variable :FactorGraphIterables.variables(root))
{
ISolverVariable svariable = solvers.getSolverVariableOrNull(variable);
if (svariable != null)
{
assertSame(variable, svariable.getModelObject());
}
}
for (Factor factor : FactorGraphIterables.factors(root))
{
ISolverFactor sfactor = solvers.getSolverFactorOrNull(factor);
if (sfactor != null)
{
assertSame(factor, sfactor.getModelObject());
}
}
Set<FactorGraph> graphs = new LinkedHashSet<>(FactorGraphIterables.subgraphs(root));
assertSame(root, Iterables.getFirst(graphs, null));
assertEquals(graphs.size(), state.getSolverSubgraphsRecursive().size());
Set<ISolverFactorGraph> sgraphs = new LinkedHashSet<>(state.getSolverSubgraphsRecursive());
assertEquals(graphs.size(), sgraphs.size());
assertSame(state, Iterables.getFirst(sgraphs, null));
for (ISolverFactorGraph sgraph : sgraphs)
{
FactorGraph graph = sgraph.getModelObject();
assert(graphs.contains(graph));
if (graph != root)
{
assertSame(sgraph, solvers.getSolverGraphOrNull(graph));
if (sgraph instanceof SFactorGraphBase)
{
assertInvariants((SFactorGraphBase<?,?,?,?>)sgraph);
}
}
for (Variable var : graph.getOwnedVariables())
{
ISolverVariable svar = requireNonNull(solvers.getSolverVariableOrNull(var));
assertSame(var, svar.getModelObject());
if (graph == root)
{
assertSame(svar, state.getSolverVariable(var,false));
}
}
Set<Variable> ownedVars = new LinkedHashSet<>(graph.getOwnedVariables());
Set<ISolverVariable> ownedSVars = new LinkedHashSet<>(sgraph.getSolverVariables());
assertEquals(ownedVars.size(), ownedSVars.size());
for (ISolverVariable svar : ownedSVars)
{
assertTrue(ownedVars.contains(svar.getModelObject()));
}
for (Factor factor : graph.getOwnedFactors())
{
ISolverFactor sfactor = requireNonNull(solvers.getSolverFactorOrNull(factor));
assertSame(factor, sfactor.getModelObject());
if (graph == root)
{
assertSame(sfactor, state.getSolverFactor(factor, false));
}
}
Set<Factor> ownedFactors = new LinkedHashSet<>(graph.getOwnedFactors());
Set<ISolverFactor> ownedSFactors = new LinkedHashSet<>(sgraph.getSolverFactors());
assertEquals(ownedFactors.size(), ownedSFactors.size());
for (ISolverFactor sfactor : ownedSFactors)
{
assertTrue(ownedFactors.contains(sfactor.getModelObject()));
}
}
Set<Variable> allVars = new LinkedHashSet<>(FactorGraphIterables.variables(root));
Set<ISolverVariable> allSVars = new LinkedHashSet<>(state.getSolverVariablesRecursive());
assertEquals(allVars.size(), allSVars.size());
for (ISolverVariable svar : allSVars)
{
assertTrue(allVars.contains(svar.getModelObject()));
}
Set<Factor> allFactors = new LinkedHashSet<>(FactorGraphIterables.factors(root));
Set<ISolverFactor> allSFactors = new LinkedHashSet<>(state.getSolverFactorsRecursive());
assertEquals(allFactors.size(), allSFactors.size());
for (ISolverFactor sfactor : allSFactors)
{
assertTrue(allFactors.contains(sfactor.getModelObject()));
}
Discrete looseVar = new Bit();
looseVar.setName("looseVar");
expectThrow(IllegalArgumentException.class, "'looseVar' does not belong to graph.",
state, "getSolverVariable", looseVar, true);
FactorGraph otherGraph = new FactorGraph();
otherGraph.setName("otherGraph");
Discrete a = new Bit(); a.setName("a");
otherGraph.addVariables(a);
}
}