package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDefinition import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.PropagationModality import java.util.Map import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExpressionEvaluation import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* import java.util.LinkedList import java.util.List import org.eclipse.xtend.lib.annotations.Data import java.util.HashMap import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall import java.util.Comparator import java.util.ArrayList import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PDisjunction import java.util.LinkedHashSet @Data class UnitPropagation { val PQuery q val PConstraint c val PropagationModality pm val Modality m3 } @Data class UnitPropagationPreconditionGenerationResult { List definitions= new LinkedList Map unitPropagation2PatternName = new HashMap Map constraintOccurence2Name = new HashMap def registerQuery(PQuery q, PConstraint c, PropagationModality pm, Modality m3, String patternName, CharSequence definition) { val key = new UnitPropagation(q,c,pm,m3) definitions += definition unitPropagation2PatternName.put(key,patternName) } def registerUnsatQuery(PQuery q, PConstraint c, PropagationModality pm, Modality m3) { val key = new UnitPropagation(q,c,pm,m3) unitPropagation2PatternName.put(key,null) } def contains(PQuery q, PConstraint c, PropagationModality pm, Modality m3) { val key = new UnitPropagation(q,c,pm,m3) return unitPropagation2PatternName.containsKey(key) } def getName(PQuery q, PConstraint c, PropagationModality pm, Modality m3) { val key = new UnitPropagation(q,c,pm,m3) return key.lookup(unitPropagation2PatternName) } def isDefined(PQuery q, PConstraint c, PropagationModality pm, Modality m3) { val key = new UnitPropagation(q,c,pm,m3) return unitPropagation2PatternName.get(key) !== null } } @Data class UnitPropagationPreconditionFinalResult { CharSequence definitions HashMap constraint2MustPreconditionName HashMap constraint2CurrentPreconditionName } class UnitPropagationPreconditionGenerator { val PatternGenerator base val PConstraintTransformer constraintTransformer; new(PatternGenerator patternGenerator) { this.base = patternGenerator this.constraintTransformer = new PConstraintTransformer(base.relationDefinitionIndexer) } def generateUnitPropagationRules( LogicProblem problem, Iterable relations, Map fqn2PQuery) { // Create an empty result val res = new UnitPropagationPreconditionGenerationResult val wfs = base.wfQueries(problem)//.map[it.patternPQuery] val Map>> mainMustPropagationNames = new HashMap val Map>> mainCurrentPropagationNames = new HashMap for(wf : wfs) { val query = wf.patternPQuery as PQuery val relation = wf.target val allReferredChecks = allReferredConstraints(relation,query).filter(ExpressionEvaluation) for(referredCheck : allReferredChecks) { val mustPropagationPrecondition = getOrGeneratePropagationRule(res,relation,query,referredCheck,PropagationModality::UP, Modality::MUST) val currentPropagationPrecondition = getOrGeneratePropagationRule(res,relation,query,referredCheck,PropagationModality::UP, Modality::CURRENT) if(!mainMustPropagationNames.containsKey(referredCheck)) { mainMustPropagationNames.put(referredCheck,new LinkedList) } if(!mainCurrentPropagationNames.containsKey(referredCheck)) { mainCurrentPropagationNames.put(referredCheck,new LinkedList) } if(mustPropagationPrecondition !== null) { mainMustPropagationNames.get(referredCheck).add(mustPropagationPrecondition->query.parameterNames.size) } if(currentPropagationPrecondition !== null) { mainCurrentPropagationNames.get(referredCheck).add(currentPropagationPrecondition->query.parameterNames.size) } } } val preconditions = new LinkedList val constraint2MustPrecondition = new HashMap val constraint2CurrentPrecondition = new HashMap for(entry : mainMustPropagationNames.entrySet) { val name = '''UPMUSTPropagate_«res.getOrGenerateConstraintName(entry.key)»'''; val def = ''' pattern «name»(«FOR index : 1..entry.key.arity SEPARATOR ", "»«canonizeName(index,PropagationModality::UP)»«ENDFOR») «FOR propagation : entry.value SEPARATOR " or "» { find «propagation.key»(problem,interpretation,«FOR index : 0..(){ override compare(PVariable o1, PVariable o2) { o1.name.compareTo(o2.name) } } val variablesInOrder = new ArrayList(c.affectedVariables) variablesInOrder.toList.sort(comparator) return '''«FOR variableIndex : 1..variablesInOrder.size»«variablesInOrder.get(variableIndex-1).canonizeName»==«canonizeName(variableIndex,m)»;«ENDFOR»''' } def dispatch propagateVariables(PConstraint c, PropagationModality m) { throw new UnsupportedOperationException('''Constraint not supported: «c.class.simpleName»''') } def dispatch arity(ExpressionEvaluation c) { c.affectedVariables.size } def dispatch arity(PConstraint c) { throw new UnsupportedOperationException('''Constraint not supported: «c.class.simpleName»''') } }