package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation import java.util.Iterator import org.eclipse.viatra.query.runtime.api.IPatternMatch import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor @FinalFieldsConstructor abstract class MultiplicityCalculator { val ViatraQueryMatcher matcher def getMultiplicity() { val iterator = matcher.streamAllMatches.iterator getMultiplicity(iterator) } def getMultiplicity(PartialInterpretation interpretation) { val partialMatch = matcher.newEmptyMatch partialMatch.set(0, interpretation.problem) partialMatch.set(1, interpretation) val iterator = matcher.streamAllMatches(partialMatch).iterator getMultiplicity(iterator) } protected def int getMultiplicity(Iterator iterator) } class RemainingMultiplicityCalculator extends MultiplicityCalculator { val int bound @FinalFieldsConstructor private new() { } protected override getMultiplicity(Iterator iterator) { var res = 0 while (iterator.hasNext) { val match = iterator.next val existingMultiplicity = match.get(3) as Integer if (existingMultiplicity < bound) { res += bound - existingMultiplicity } } res } static def of(ViatraQueryMatcher matcher, int bound) { if (bound < 0) { new RemainingInfiniteMultiplicityCalculator(matcher) } else { new RemainingMultiplicityCalculator(matcher, bound) } } } package class RemainingInfiniteMultiplicityCalculator extends MultiplicityCalculator { @FinalFieldsConstructor package new() { } protected override getMultiplicity(Iterator iterator) { if (iterator.hasNext) { -1 } else { 0 } } } @FinalFieldsConstructor class UnrepairableMultiplicityCalculator extends MultiplicityCalculator { val int lowerBound override protected getMultiplicity(Iterator iterator) { var res = 0 while (iterator.hasNext) { val match = iterator.next val existingMultiplicity = match.get(3) as Integer if (existingMultiplicity < lowerBound) { val missingMultiplcity = lowerBound - existingMultiplicity val numerOfRepairMatches = match.get(4) as Integer val unrepairableMultiplicty = missingMultiplcity - numerOfRepairMatches if (unrepairableMultiplicty > res) { res = unrepairableMultiplicty } } } res } } @FinalFieldsConstructor class RemainingInverseMultiplicityCalculator extends MultiplicityCalculator { val int upperBound override protected getMultiplicity(Iterator iterator) { var res = 0 while (iterator.hasNext) { val match = iterator.next val existingMultiplicity = match.get(3) as Integer if (existingMultiplicity < upperBound) { val availableMultiplicity = upperBound - existingMultiplicity val numberOfRepairMatches = match.get(4) as Integer res += Math.min(availableMultiplicity, numberOfRepairMatches) } } res } }