/******************************************************************************* * Copyright 2014 Felipe Takiyama * * 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 br.usp.poli.takiyama.acfove; import br.usp.poli.takiyama.common.Marginal; import br.usp.poli.takiyama.common.Parfactor; import br.usp.poli.takiyama.common.SplitResult; import br.usp.poli.takiyama.common.StdMarginal.StdMarginalBuilder; import br.usp.poli.takiyama.prv.Binding; import br.usp.poli.takiyama.prv.Constant; import br.usp.poli.takiyama.prv.LogicalVariable; import br.usp.poli.takiyama.prv.Population; import br.usp.poli.takiyama.prv.Substitution; /** * This operation executes a split on a parfactor for every * constant in the population of a free logical variable that appears in this * parfactor. * <p> * Given a set of parfactors, it is always possible to propositionalize it on a * free logical variable. * </p> * <p> * After all the splits, the {@link Shatter} macro operation is invoked to * guarantee that all parameterized random variables represent equal or * disjoint sets of random variables. * </p> */ public final class Propositionalize implements MacroOperation { private Marginal marginal; private final Parfactor propositionalizable; private final LogicalVariable freeVariable; public Propositionalize(Marginal marginal, Parfactor propositionalizable, LogicalVariable freeVariable) { this.marginal = marginal; this.propositionalizable = propositionalizable; this.freeVariable = freeVariable; } @Override public Marginal run() { Parfactor splittable = propositionalizable; StdMarginalBuilder resultBuilder = new StdMarginalBuilder(); resultBuilder.add(marginal).remove(propositionalizable); Population population = getIndividuals(); for (Constant individual : population) { Substitution sub = Substitution.getInstance( Binding.getInstance(freeVariable, individual)); if (splittable.isSplittable(sub)) { SplitResult splitResult = splittable.splitOn(sub); resultBuilder.add(splitResult.result()); if (splitResult.residue().size() == 1) { splittable = splitResult.residue().iterator().next(); } else { throw new IllegalStateException("Split result has more than 1 residue!"); } } else { resultBuilder.add(splittable); } } // Shatters the new marginal and returns the result Marginal result = new Shatter(resultBuilder.build()).run(); return result; } /** * Returns free logical variable population that satisfies constraints * from the parfactor being propositionalized. */ private Population getIndividuals() { return freeVariable.individualsSatisfying(propositionalizable.constraints()); } /* * The cost of propositionalization is given by the following expression: * <p> * |F| x |D(X):C| * </p> * <p> * where * </p> * <li> |F| is factor component size from parfactor being propositionalized * <li> |D(X):C| is the number of free logical variable individuals * satisfying constraints from the parfactor being propositionalized * <p> * Propositionalization actually creates many factors with the same size * as the original parfactor. Thus, the cost would have to be the size of * the parfactor being propositionalized. Nevertheless, this macro-operation * is called when no other operation is possible, because it 'destroys' * lifted elimination. The above expression makes this operation more * expensive. * </p> */ /** * Returns infinity - 1. This operation is only feasible when no other * operation is possible. */ @Override public int cost() { return ((int) Double.POSITIVE_INFINITY) - 1; } /** * Returns zero. */ @Override public int numberOfRandomVariablesEliminated() { return 0; } @Override public String toString() { // StringBuilder builder = new StringBuilder(); // builder.append("PROPOSITIONALIZE").append("\n") // .append(propositionalizable).append("\n") // .append(freeVariable); // return builder.toString(); return ""; } }