From 60f01f46ba232ed6416054f0a6115cb2a9b70b4e Mon Sep 17 00:00:00 2001 From: OszkarSemerath Date: Sat, 10 Jun 2017 19:05:05 +0200 Subject: Migrating Additional projects --- ...nterpretation2NeighbourhoodRepresentation.xtend | 345 +++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend') diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend new file mode 100644 index 00000000..df6fb6ae --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend @@ -0,0 +1,345 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood + +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation +import java.util.HashMap +import java.util.HashSet +import java.util.LinkedList +import java.util.List +import java.util.Map +import java.util.Set + +import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* + +abstract class PartialInterpretation2NeighbourhoodRepresentation { + private val boolean deepRepresentation + private val boolean mergeSimilarNeighbourhood + + protected new(boolean deeprepresentation, boolean mergeSimilarNeighbourhood) { + this.deepRepresentation = deeprepresentation + this.mergeSimilarNeighbourhood = mergeSimilarNeighbourhood + } + + public static val FixPointRage = -1 + public static val FullParallels = Integer.MAX_VALUE + public static val MaxNumbers = Integer.MAX_VALUE + + /** + * Creates a neighbourhood representation with traces + * @param model The model to be represented. + * @param range The range of the neighbourhood. + * @param parallels The maximal number of parallel references to be differentiated. + */ + def public createRepresentation(PartialInterpretation model, int range, int parallels, int maxNumber) { + return createRepresentation(model,range,parallels,maxNumber,null,null) + } + + def public createRepresentation( + PartialInterpretation model, + int range, int parallels, int maxNumber, + Set relevantTypes, Set relevantRelations) + { + val Map> types = new HashMap + fillTypes(model,types,relevantTypes) + val Map>> IncomingRelations = new HashMap; + val Map>> OutgoingRelations = new HashMap; + fillReferences(model,IncomingRelations,OutgoingRelations,relevantRelations) + + val res = doRecursiveNeighbourCalculation(model,types,IncomingRelations,OutgoingRelations,range,parallels,maxNumber); + + return res; + } + + def private isRelevant(TypeDeclaration t, Set relevantTypes) { + if(relevantTypes === null) { + return true + } else { + return relevantTypes.contains(t) + } + } + def private isRelevant(RelationDeclaration r, Set relevantRelations) { + if(relevantRelations === null) { + return true + } else { + return relevantRelations.contains(r) + } + } + + /** + * Creates a neighbourhood representation with traces + * @param model The model to be represented. + * @param IncomingRelations Requires the previously indexed incoming references. + * @param OutgoingRelations Requires the previously indexed outgoing references. + * @param range The range of the neighbourhood. + * @param parallels The maximal number of parallel references to be differentiated. + */ + def private NeighbourhoodWithTraces doRecursiveNeighbourCalculation( + PartialInterpretation model, + Map> types, + Map>> IncomingRelations, + Map>> OutgoingRelations, + int range, int parallels, int maxNumber) + { + if(range == 0){ + val r = calculateLocalNodeDescriptors(model,types,maxNumber) + val res = this.createLocalRepresentation(r.value,r.key) + if(res.modelRepresentation === null) { + throw new IllegalArgumentException('''Model representation is null''') + } else if(res.nodeRepresentations === null || res.nodeRepresentations.empty) { + throw new IllegalArgumentException('''No node representation''') + } else if(res.previousRepresentation !== null) { + throw new IllegalArgumentException('''The previous representation of the first neighbourhood have to be null''') + } else return res + } else if(range > 0) { + val previous = doRecursiveNeighbourCalculation(model,types,IncomingRelations,OutgoingRelations,range-1,parallels,maxNumber) + val r = calculateFurtherNodeDescriptors(model,previous,IncomingRelations,OutgoingRelations,parallels,maxNumber) + //println('''Level «range» finished.''') + val res = createFurtherRepresentation(r.key,r.value,previous,deepRepresentation) + if(res.modelRepresentation === null) { + throw new IllegalArgumentException('''Model representation is null''') + } else if(res.nodeRepresentations === null || res.nodeRepresentations.empty) { + throw new IllegalArgumentException('''No node representation''') + } else if(res.previousRepresentation === null && deepRepresentation) { + throw new IllegalArgumentException('''Need previous representations''') + } else return res + } else if (range == FixPointRage) { + return refineUntilFixpoint(model,types,IncomingRelations,OutgoingRelations,parallels,maxNumber) + } + } + + def private refineUntilFixpoint( + PartialInterpretation model, + Map> types, + Map>> IncomingRelations, + Map>> OutgoingRelations, + int parallels, int maxNumbers) + { + var lastRange = 0 + val last = calculateLocalNodeDescriptors(model,types,maxNumbers) + var lastRepresentation = this.createLocalRepresentation(last.value,last.key) + //println('''Level 0 finished.''') + var boolean hasRefined + do { + val nextRange = lastRange+1 + val next = calculateFurtherNodeDescriptors(model,lastRepresentation,IncomingRelations,OutgoingRelations,parallels,maxNumbers) + val nextRepresentation = createFurtherRepresentation(next.key,next.value,lastRepresentation,deepRepresentation) + + val previousNumberOfTypes =lastRepresentation.nodeRepresentations.values.toSet.size + val nextNumberOfTypes = nextRepresentation.nodeRepresentations.values.toSet.size + hasRefined = nextNumberOfTypes > previousNumberOfTypes + + lastRange = nextRange + lastRepresentation = nextRepresentation + +// if(hasRefined) { +// println('''Level «nextRange» is calculated, number of types is refined: «previousNumberOfTypes» -> «nextNumberOfTypes»''') +// } else { +// println('''Level «nextRange» is calculated, but the number of types is not refined: «previousNumberOfTypes» = «nextNumberOfTypes»''') +// } + } while (hasRefined) + return lastRepresentation + } + + def private getElements(PartialInterpretation model) { + return model.problem.elements + model.newElements + } + + def private fillTypes(PartialInterpretation model, Map> node2Type, Set relevantTypes) { + for(element : model.elements) { + node2Type.put(element, new HashSet) + } + +// for(typeDefinition : model.problem.types.filter(TypeDefinition)) { +// // Dont need +// } + for(typeInterpretation : model.partialtypeinterpratation) { + val type = typeInterpretation.interpretationOf + if(type.isRelevant(relevantTypes)) { + for(element : typeInterpretation.elements) { + element.lookup(node2Type).add(type.name) + } + } + } + } + + /** + * Indexes the references + */ + def private fillReferences(PartialInterpretation model, + Map>> IncomingRelations, + Map>> OutgoingRelations, + Set relevantRelations) + { + for(object : model.elements) { + IncomingRelations.put(object,new LinkedList) + OutgoingRelations.put(object,new LinkedList) + } + for(relationInterpretation : model.partialrelationinterpretation) { + val type = relationInterpretation.interpretationOf + if(type.isRelevant(relevantRelations)) { + for(link : relationInterpretation.relationlinks) { + if(link instanceof BinaryElementRelationLink) { + OutgoingRelations.get(link.param1) += new OutgoingRelation(link.param2,type.name) + IncomingRelations.get(link.param2) += new IncomingRelation(link.param1,type.name) + } else throw new UnsupportedOperationException + } + } + } + } + + /** + * Creates a local representation of the objects (aka zero range neighbourhood) + */ + def abstract protected NeighbourhoodWithTraces createLocalRepresentation( + Map node2Representation, + Map representation2Amount + ) + + /** + * Creates a + */ + def abstract protected NeighbourhoodWithTraces createFurtherRepresentation( + Map, Integer> nodeDescriptors, + Map> node2Representation, + NeighbourhoodWithTraces previous, + boolean deepRepresentation + ) + + def private addOne(int original, int max) { + if(original == Integer.MAX_VALUE) return Integer.MAX_VALUE + if(original +1 > max) return Integer.MAX_VALUE + else return original+1 + } + + private def calculateIncomingEdges(Map>> IncomingRelations, + DefinedElement object, Map previousNodeRepresentations, int parallel) + { + val Map, Integer> res = new HashMap + for (incomingConcreteEdge : IncomingRelations.get(object)) { + val IncomingRelation e = new IncomingRelation( + previousNodeRepresentations.get(incomingConcreteEdge.from), incomingConcreteEdge.type) + if (res.containsKey(e)) { + res.put(e, addOne(res.get(e),parallel)) + } else { + res.put(e, 1) + } + } + return res + } + + private def calcuateOutgoingEdges(Map>> OutgoingRelations, + DefinedElement object, Map previousNodeRepresentations, int parallel) + { + val Map,Integer> res= new HashMap + for(outgoingConcreteEdge : OutgoingRelations.get(object)) { + val OutgoingRelation e = + new OutgoingRelation( + previousNodeRepresentations.get(outgoingConcreteEdge.to), + outgoingConcreteEdge.type) + if(res.containsKey(e)) { + res.put(e,addOne(res.get(e),parallel)) + } else { + res.put(e,1) + } + } + return res; + } + + /*def private void addOrCreate_Set(Map> map, KEY key, VALUE value) { + var Set s; + if(map.containsKey(key)) { + s = map.get(key); + } else { + s = new HashSet + map.put(key,s) + } + s.add(value) + }*/ + + + private def calculateFurtherNodeDescriptors( + PartialInterpretation model, + NeighbourhoodWithTraces previous, + Map>> IncomingRelations, + Map>> OutgoingRelations, + int parallels, int maxNumber) + { + val previousNodeRepresentations = previous.nodeRepresentations + val node2Representation = new HashMap> + val Map,Integer> descriptor2Number = + if(this.mergeSimilarNeighbourhood){ new HashMap } else { null } + val Map,FurtherNodeDescriptor> uniqueDescription = + if(this.mergeSimilarNeighbourhood){ new HashMap } else { null } + + for(object: model.elements) { + val incomingEdges = this.calculateIncomingEdges(IncomingRelations, object, previousNodeRepresentations,parallels) + val outgoingEdges = this.calcuateOutgoingEdges(OutgoingRelations,object, previousNodeRepresentations,parallels) + + val previousType = previousNodeRepresentations.get(object) + + if(previousType === null) { + println("Error in state coder") + } + + val nodeDescriptor = new FurtherNodeDescriptor( + previousType, + incomingEdges, + outgoingEdges) + + if(this.mergeSimilarNeighbourhood) { + if(descriptor2Number.containsKey(nodeDescriptor)) { + descriptor2Number.put( + nodeDescriptor, + addOne(descriptor2Number.get(nodeDescriptor),maxNumber) + ) + node2Representation.put(object,uniqueDescription.get(nodeDescriptor)) + } else { + descriptor2Number.put(nodeDescriptor,1) + uniqueDescription.put(nodeDescriptor,nodeDescriptor) + node2Representation.put(object,nodeDescriptor) + } + } else { + node2Representation.put(object,nodeDescriptor) + } + } + + return descriptor2Number -> node2Representation + } + + private def calculateLocalNodeDescriptors( + PartialInterpretation model, + Map> types, + int maxNumber) + { + val Map node2Representation = new HashMap + val Map representation2Amount = + if(mergeSimilarNeighbourhood){ new HashMap } else { null } + val Map uniqueRepresentation = + if(this.mergeSimilarNeighbourhood){ new HashMap } else { null } + + for(element : model.elements) { + var newDescriptor = new LocalNodeDescriptor(element.name,element.lookup(types)) + if(this.mergeSimilarNeighbourhood){ + if(uniqueRepresentation.containsKey(newDescriptor)) { + newDescriptor = newDescriptor.lookup(uniqueRepresentation) + node2Representation.put(element,newDescriptor) + representation2Amount.put( + newDescriptor, + addOne(newDescriptor.lookup(representation2Amount),maxNumber) + ) + } else { + uniqueRepresentation.put(newDescriptor,newDescriptor) + node2Representation.put(element,newDescriptor) + representation2Amount.put(newDescriptor, 1) + } + } else { + node2Representation.put(element,newDescriptor) + } + } + + return representation2Amount -> node2Representation + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2