/**
* SPINdle (version 2.2.2)
* Copyright (C) 2009-2012 NICTA Ltd.
*
* This file is part of SPINdle project.
*
* SPINdle is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SPINdle is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with SPINdle. If not, see <http://www.gnu.org/licenses/>.
*
* @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory
*/
package spindle.engine.tdl;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import spindle.core.dom.Conclusion;
import spindle.core.dom.ConclusionType;
import spindle.core.dom.Literal;
import spindle.core.dom.LiteralComparator;
import spindle.core.dom.Temporal;
import spindle.engine.ReasoningEngineException;
public class TdlReasoningUtilities {
private static final Comparator<Literal> PLAIN_LITERAL_COMPARATOR = new LiteralComparator(false);
private static final Temporal PERSISTENT_TEMPORAL = new Temporal();
public static Map<Literal, Set<Literal>> consolidateLiteralsTemporals(Collection<Literal> literals) throws ReasoningEngineException {
Map<Literal, Set<Temporal>> temporals = joinLiteralsTemporals(literals);
Map<Literal, Set<Literal>> joinedLiterals = new TreeMap<Literal, Set<Literal>>(PLAIN_LITERAL_COMPARATOR);
for (Entry<Literal, Set<Temporal>> entry : temporals.entrySet()) {
Literal literal = entry.getKey();
Set<Temporal> literalTemporals = entry.getValue();
Set<Literal> literalsSet = new TreeSet<Literal>();
for (Temporal temporal : literalTemporals) {
literalsSet.add(temporal.hasTemporalInfo() ? literal : getNewLiteral(literal, temporal));
}
joinedLiterals.put(literal, literalsSet);
}
return joinedLiterals;
}
public static Map<Literal, Set<Temporal>> joinLiteralsTemporals(Collection<Literal> literals) {
Map<Literal, Set<Temporal>> temporals = new TreeMap<Literal, Set<Temporal>>(PLAIN_LITERAL_COMPARATOR);
for (Literal literal : literals) {
Set<Temporal> literalTemporals = temporals.get(literal);
if (null == literalTemporals) {
literalTemporals = new TreeSet<Temporal>();
temporals.put(literal.cloneWithNoTemporal(), literalTemporals);
}
Temporal t = literal.getTemporal();
literalTemporals.add(null == t ? PERSISTENT_TEMPORAL : t);
}
// try {
for (Entry<Literal, Set<Temporal>> entry : temporals.entrySet()) {
Set<Temporal> literalTemporals = entry.getValue();
Temporal.consolidateTemporalSegments(literalTemporals);
// if (literalTemporals.contains(PERSISTENT_TEMPORAL)) {
// literalTemporals.clear();
// literalTemporals.add(PERSISTENT_TEMPORAL);
// } else {
// Temporal newTemporal = null;
// for (Temporal temporal : new TreeSet<Temporal>(literalTemporals)) {
// if (null == newTemporal) {
// literalTemporals.clear();
// newTemporal = temporal;
// } else {
// if (newTemporal.overlapOrMeet(temporal)) {
// newTemporal = newTemporal.join(temporal);
// } else {
// literalTemporals.add(newTemporal);
// newTemporal = temporal;
// }
// }
// }
// }
}
// } catch (TemporalException e) {
// }
return temporals;
}
public static void generateEnforcedConclusionsSet(Conclusion enforcedConclusion, Set<Conclusion> defeatedConclusions, //
boolean requireSameStartTime, //
Set<Conclusion> consolidatedConclusions, Set<Conclusion> unenforcedConclusions) throws ReasoningEngineException {
consolidatedConclusions.add(enforcedConclusion);
ConclusionType enforcedConclusionType = enforcedConclusion.getConclusionType();
// do nothing if the conclusion proved is negative
if (enforcedConclusionType.isNegativeConclusion()) {
consolidatedConclusions.addAll(defeatedConclusions);
return;
}
Temporal enforcedTemporal = enforcedConclusion.getTemporal();
// if the enforced conclusion has no temporal information
// change all defeated conclusions to negatively provability and remove their temporals.
if (null == enforcedTemporal) {
if (requireSameStartTime) {
for (Conclusion defeatedConclusion : defeatedConclusions) {
Temporal defeatedTemporal = defeatedConclusion.getTemporal();
if (null == defeatedTemporal || Long.MIN_VALUE != defeatedTemporal.getStartTime())
throw new ReasoningEngineException(TdlReasoningUtilities.class, "start time are not the same");
ConclusionType conflictDefeatedConclusionType = getNegativeConclusionType(defeatedConclusion.getConclusionType());
consolidatedConclusions.add(new Conclusion(conflictDefeatedConclusionType, defeatedConclusion.getLiteral()
.cloneWithNoTemporal()));
}
} else {
for (Conclusion defeatedConclusion : defeatedConclusions) {
ConclusionType conflictDefeatedConclusionType = getNegativeConclusionType(defeatedConclusion.getConclusionType());
consolidatedConclusions.add(new Conclusion(conflictDefeatedConclusionType, defeatedConclusion.getLiteral()
.cloneWithNoTemporal()));
}
}
return;
}
for (Conclusion defeatedConclusion : defeatedConclusions) {
Literal defeatedLiteral = defeatedConclusion.getLiteral();
ConclusionType ctDefeated = defeatedConclusion.getConclusionType();
ConclusionType ctNegative = getNegativeConclusionType(ctDefeated);
Temporal defeatedTemporal = defeatedConclusion.getTemporal();
if (null == defeatedTemporal) defeatedTemporal = PERSISTENT_TEMPORAL;
if (requireSameStartTime) {
if (!enforcedTemporal.sameStart(defeatedTemporal))
throw new ReasoningEngineException(TdlReasoningUtilities.class, "start time are not the same");
}
if (enforcedTemporal.equals(defeatedTemporal)) {
if (ctDefeated.isNegativeConclusion()) {
consolidatedConclusions.add(defeatedConclusion);
} else {
consolidatedConclusions.add(new Conclusion(ctNegative, defeatedLiteral));
}
} else {
consolidatedConclusions.add(getNewConclusion(ctNegative, defeatedLiteral, enforcedTemporal));
Temporal precedingTemporal = defeatedTemporal.startBefore(enforcedTemporal) ? new Temporal(defeatedTemporal.getStartTime(),
enforcedTemporal.getStartTime()) : null;
Temporal succeedingTemporal = defeatedTemporal.endAfter(enforcedTemporal) ? new Temporal(enforcedTemporal.getEndTime(),
defeatedTemporal.getEndTime()) : null;
if (null != precedingTemporal) {
unenforcedConclusions.add(getNewConclusion(ctDefeated, defeatedLiteral, precedingTemporal));
}
if (null != succeedingTemporal) {
unenforcedConclusions.add(getNewConclusion(ctDefeated, defeatedLiteral, succeedingTemporal));
}
}
}
}
private static ConclusionType getNegativeConclusionType(ConclusionType conclusionType) {
if (conclusionType.isNegativeConclusion()) return conclusionType;
switch (conclusionType) {
case DEFINITE_PROVABLE:
return ConclusionType.DEFINITE_NOT_PROVABLE;
case DEFEASIBLY_PROVABLE:
return ConclusionType.DEFEASIBLY_NOT_PROVABLE;
default:
return null;
}
}
private static Literal getNewLiteral(Literal literal, Temporal temporal) {
Literal newLiteral = literal.clone();
newLiteral.setTemporal(temporal.clone());
return newLiteral;
}
private static Conclusion getNewConclusion(ConclusionType conclusionType, Literal literal, Temporal temporal) {
return new Conclusion(conclusionType, getNewLiteral(literal, temporal));
}
}